[libvirt] [tck PATCH 0/3] Improvements to virtual network testing and misc fixes

The main goal of this patch series is addition of tests which create a virtual network with every possible forwarding mode, and attempt to boot a guest with them. A couple of other pieces were added at the end. Daniel P. Berrangé (3): Add tests for virtual network <-> guest connections Fix incorrect warning about deleting everything Allow tests to be listed as positional arguments bin/libvirt-tck | 69 ++++++++------- lib/Sys/Virt/TCK.pm | 33 ++++++++ lib/Sys/Virt/TCK/NetworkBuilder.pm | 33 +++++++- scripts/networks/300-guest-network-isolated.t | 82 ++++++++++++++++++ scripts/networks/310-guest-network-nat.t | 83 +++++++++++++++++++ scripts/networks/320-guest-network-route.t | 83 +++++++++++++++++++ scripts/networks/330-guest-network-open.t | 83 +++++++++++++++++++ scripts/networks/340-guest-network-bridge.t | 79 ++++++++++++++++++ scripts/networks/350-guest-network-private.t | 81 ++++++++++++++++++ scripts/networks/360-guest-network-vepa.t | 81 ++++++++++++++++++ .../networks/370-guest-network-passthrough.t | 81 ++++++++++++++++++ scripts/networks/380-guest-network-hostdev.t | 82 ++++++++++++++++++ t/080-network-builder.t | 2 +- 13 files changed, 838 insertions(+), 34 deletions(-) create mode 100644 scripts/networks/300-guest-network-isolated.t create mode 100644 scripts/networks/310-guest-network-nat.t create mode 100644 scripts/networks/320-guest-network-route.t create mode 100644 scripts/networks/330-guest-network-open.t create mode 100644 scripts/networks/340-guest-network-bridge.t create mode 100644 scripts/networks/350-guest-network-private.t create mode 100644 scripts/networks/360-guest-network-vepa.t create mode 100644 scripts/networks/370-guest-network-passthrough.t create mode 100644 scripts/networks/380-guest-network-hostdev.t -- 2.19.1

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- lib/Sys/Virt/TCK.pm | 33 ++++++++ lib/Sys/Virt/TCK/NetworkBuilder.pm | 33 +++++++- scripts/networks/300-guest-network-isolated.t | 82 ++++++++++++++++++ scripts/networks/310-guest-network-nat.t | 83 +++++++++++++++++++ scripts/networks/320-guest-network-route.t | 83 +++++++++++++++++++ scripts/networks/330-guest-network-open.t | 83 +++++++++++++++++++ scripts/networks/340-guest-network-bridge.t | 79 ++++++++++++++++++ scripts/networks/350-guest-network-private.t | 81 ++++++++++++++++++ scripts/networks/360-guest-network-vepa.t | 81 ++++++++++++++++++ .../networks/370-guest-network-passthrough.t | 81 ++++++++++++++++++ scripts/networks/380-guest-network-hostdev.t | 82 ++++++++++++++++++ t/080-network-builder.t | 2 +- 12 files changed, 800 insertions(+), 3 deletions(-) create mode 100644 scripts/networks/300-guest-network-isolated.t create mode 100644 scripts/networks/310-guest-network-nat.t create mode 100644 scripts/networks/320-guest-network-route.t create mode 100644 scripts/networks/330-guest-network-open.t create mode 100644 scripts/networks/340-guest-network-bridge.t create mode 100644 scripts/networks/350-guest-network-private.t create mode 100644 scripts/networks/360-guest-network-vepa.t create mode 100644 scripts/networks/370-guest-network-passthrough.t create mode 100644 scripts/networks/380-guest-network-hostdev.t diff --git a/lib/Sys/Virt/TCK.pm b/lib/Sys/Virt/TCK.pm index 04244bd..9457836 100644 --- a/lib/Sys/Virt/TCK.pm +++ b/lib/Sys/Virt/TCK.pm @@ -29,6 +29,7 @@ use File::Path qw(mkpath); use File::Spec::Functions qw(catfile catdir rootdir); use Cwd qw(cwd); use LWP::UserAgent; +use IO::Interface::Simple; use IO::Uncompress::Gunzip qw(gunzip); use IO::Uncompress::Bunzip2 qw(bunzip2); use XML::XPath; @@ -1285,6 +1286,38 @@ sub get_ip_from_leases{ } +sub find_free_ipv4_subnet { + my $index; + + my %used; + + foreach my $iface (IO::Interface::Simple->interfaces()) { + if ($iface->netmask eq "255.255.255.0" && + $iface->address =~ /^192.168.(\d+).\d+/) { + $used{"$1"} = 1; + print "Used $1\n"; + } else { + print "Not used ", $iface->address, "\n"; + } + } + + for (my $i = 1; $i < 255; $i++) { + if (!exists $used{"$i"}) { + $index = $i; + last; + } + } + + return () unless defined $index; + + return ( + address => "192.168.$index.1", + netmask => "255.255.255.0", + dhcpstart => "192.168.$index.100", + dhcpend => "192.168.$index.200" + ); +} + sub shutdown_vm_gracefully { my $dom = shift; diff --git a/lib/Sys/Virt/TCK/NetworkBuilder.pm b/lib/Sys/Virt/TCK/NetworkBuilder.pm index 09ca6b7..ad0cab8 100644 --- a/lib/Sys/Virt/TCK/NetworkBuilder.pm +++ b/lib/Sys/Virt/TCK/NetworkBuilder.pm @@ -61,6 +61,22 @@ sub forward { return $self; } +sub interfaces { + my $self = shift; + + $self->{interfaces} = [@_]; + + return $self; +} + +sub host_devices { + my $self = shift; + + $self->{host_devices} = [@_]; + + return $self; +} + sub ipaddr { my $self = shift; my $address = shift; @@ -98,8 +114,21 @@ sub as_xml { $w->emptyTag("bridge", %{$self->{bridge}}) if $self->{bridge}; - $w->emptyTag("forward", %{$self->{forward}}) - if exists $self->{forward}; + if (exists $self->{forward}) { + $w->startTag("forward", %{$self->{forward}}); + foreach (@{$self->{interfaces}}) { + $w->emptyTag("interface", dev => $_); + } + foreach (@{$self->{host_devices}}) { + $w->emptyTag("address", + type => "pci", + domain => $_->[0], + bus => $_->[1], + slot => $_->[2], + function => $_->[3]); + } + $w->endTag("forward"); + } if ($self->{ipaddr}) { $w->startTag("ip", diff --git a/scripts/networks/300-guest-network-isolated.t b/scripts/networks/300-guest-network-isolated.t new file mode 100644 index 0000000..487e864 --- /dev/null +++ b/scripts/networks/300-guest-network-isolated.t @@ -0,0 +1,82 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/300-guest-network-isolated.t - guest connect to isolated network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to an isolated +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my %subnet = Sys::Virt::TCK->find_free_ipv4_subnet(); + +SKIP: { + skip "No available IPv4 subnet", 4 unless defined $subnet{address}; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->bridge("tck"); + $b->ipaddr($subnet{address}, $subnet{netmask}); + $b->dhcp_range($subnet{dhcpstart}, $subnet{dhcpend}); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + + $b = $tck->generic_domain(name => "tck"); + $b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11"); + $xml = $b->as_xml(); + + diag "Creating a new transient domain"; + diag $xml; + my $dom; + ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + + diag "Destroying the transient guest"; + $dom->destroy; + + diag "Checking that transient domain has gone away"; + ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + + diag "Destroying the transient network"; + $net->destroy; + + diag "Checking that transient network has gone away"; + ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); +} + +# end diff --git a/scripts/networks/310-guest-network-nat.t b/scripts/networks/310-guest-network-nat.t new file mode 100644 index 0000000..fe1a926 --- /dev/null +++ b/scripts/networks/310-guest-network-nat.t @@ -0,0 +1,83 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/310-guest-network-nat.t - guest connect to nat network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to a nat +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my %subnet = Sys::Virt::TCK->find_free_ipv4_subnet(); + +SKIP: { + skip "No available IPv4 subnet", 4 unless defined $subnet{address}; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->bridge("tck"); + $b->forward(mode => "nat"); + $b->ipaddr($subnet{address}, $subnet{netmask}); + $b->dhcp_range($subnet{dhcpstart}, $subnet{dhcpend}); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + + $b = $tck->generic_domain(name => "tck"); + $b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11"); + $xml = $b->as_xml(); + + diag "Creating a new transient domain"; + diag $xml; + my $dom; + ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + + diag "Destroying the transient guest"; + $dom->destroy; + + diag "Checking that transient domain has gone away"; + ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + + diag "Destroying the transient network"; + $net->destroy; + + diag "Checking that transient network has gone away"; + ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); +} + +# end diff --git a/scripts/networks/320-guest-network-route.t b/scripts/networks/320-guest-network-route.t new file mode 100644 index 0000000..91f0b70 --- /dev/null +++ b/scripts/networks/320-guest-network-route.t @@ -0,0 +1,83 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/320-guest-network-route.t - guest connect to routed network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to a routed +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my %subnet = Sys::Virt::TCK->find_free_ipv4_subnet(); + +SKIP: { + skip "No available IPv4 subnet", 4 unless defined $subnet{address}; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->bridge("tck"); + $b->forward(mode => "route"); + $b->ipaddr($subnet{address}, $subnet{netmask}); + $b->dhcp_range($subnet{dhcpstart}, $subnet{dhcpend}); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + + $b = $tck->generic_domain(name => "tck"); + $b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11"); + $xml = $b->as_xml(); + + diag "Creating a new transient domain"; + diag $xml; + my $dom; + ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + + diag "Destroying the transient guest"; + $dom->destroy; + + diag "Checking that transient domain has gone away"; + ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + + diag "Destroying the transient network"; + $net->destroy; + + diag "Checking that transient network has gone away"; + ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); +} + +# end diff --git a/scripts/networks/330-guest-network-open.t b/scripts/networks/330-guest-network-open.t new file mode 100644 index 0000000..113f4cc --- /dev/null +++ b/scripts/networks/330-guest-network-open.t @@ -0,0 +1,83 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/330-guest-network-open.t - guest connect to open network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to an open +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my %subnet = Sys::Virt::TCK->find_free_ipv4_subnet(); + +SKIP: { + skip "No available IPv4 subnet", 4 unless defined $subnet{address}; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->bridge("tck"); + $b->forward(mode => "open"); + $b->ipaddr($subnet{address}, $subnet{netmask}); + $b->dhcp_range($subnet{dhcpstart}, $subnet{dhcpend}); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + + $b = $tck->generic_domain(name => "tck"); + $b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11"); + $xml = $b->as_xml(); + + diag "Creating a new transient domain"; + diag $xml; + my $dom; + ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + + diag "Destroying the transient guest"; + $dom->destroy; + + diag "Checking that transient domain has gone away"; + ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + + diag "Destroying the transient network"; + $net->destroy; + + diag "Checking that transient network has gone away"; + ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); +} + +# end diff --git a/scripts/networks/340-guest-network-bridge.t b/scripts/networks/340-guest-network-bridge.t new file mode 100644 index 0000000..e5db0ff --- /dev/null +++ b/scripts/networks/340-guest-network-bridge.t @@ -0,0 +1,79 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/340-guest-network-bridge.t - guest connect to bridge network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to a bridge +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +((system "brctl addbr tck") == 0) or die "cannot create bridge 'tck'"; + +END { system "brctl delbr tck" } + +my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); +$b->bridge("tck"); +$b->forward(mode => "bridge"); +my $xml = $b->as_xml(); + +diag "Creating a new transient network"; +diag $xml; +my $net; +ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + +$b = $tck->generic_domain(name => "tck"); +$b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11"); +$xml = $b->as_xml(); + +diag "Creating a new transient domain"; +diag $xml; +my $dom; +ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + +diag "Destroying the transient guest"; +$dom->destroy; + +diag "Checking that transient domain has gone away"; +ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + +diag "Destroying the transient network"; +$net->destroy; + +diag "Checking that transient network has gone away"; +ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); + +# end diff --git a/scripts/networks/350-guest-network-private.t b/scripts/networks/350-guest-network-private.t new file mode 100644 index 0000000..0b98149 --- /dev/null +++ b/scripts/networks/350-guest-network-private.t @@ -0,0 +1,81 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/350-guest-network-private.t - guest connect to private network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to a private +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my $hostnet = $tck->get_host_network_device(); + +SKIP: { + skip "No host device available", 4 unless $hostnet; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->forward(mode => "private"); + $b->interfaces($hostnet); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + + $b = $tck->generic_domain(name => "tck"); + $b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11"); + $xml = $b->as_xml(); + + diag "Creating a new transient domain"; + diag $xml; + my $dom; + ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + + diag "Destroying the transient guest"; + $dom->destroy; + + diag "Checking that transient domain has gone away"; + ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + + diag "Destroying the transient network"; + $net->destroy; + + diag "Checking that transient network has gone away"; + ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); +} + +# end diff --git a/scripts/networks/360-guest-network-vepa.t b/scripts/networks/360-guest-network-vepa.t new file mode 100644 index 0000000..f32ad28 --- /dev/null +++ b/scripts/networks/360-guest-network-vepa.t @@ -0,0 +1,81 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/360-guest-network-vepa.t - guest connect to vepa network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to a VEPA +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my $hostnet = $tck->get_host_network_device(); + +SKIP: { + skip "No host device available", 4 unless $hostnet; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->forward(mode => "vepa"); + $b->interfaces($hostnet); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + + $b = $tck->generic_domain(name => "tck"); + $b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11"); + $xml = $b->as_xml(); + + diag "Creating a new transient domain"; + diag $xml; + my $dom; + ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + + diag "Destroying the transient guest"; + $dom->destroy; + + diag "Checking that transient domain has gone away"; + ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + + diag "Destroying the transient network"; + $net->destroy; + + diag "Checking that transient network has gone away"; + ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); +} + +# end diff --git a/scripts/networks/370-guest-network-passthrough.t b/scripts/networks/370-guest-network-passthrough.t new file mode 100644 index 0000000..ebd210d --- /dev/null +++ b/scripts/networks/370-guest-network-passthrough.t @@ -0,0 +1,81 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/370-guest-network-passthrough.t - guest connect to passthrough network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to a passthrough +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my $hostnet = $tck->get_host_network_device(); + +SKIP: { + skip "No host device available", 4 unless $hostnet; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->forward(mode => "passthrough"); + $b->interfaces($hostnet); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + + $b = $tck->generic_domain(name => "tck"); + $b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11"); + $xml = $b->as_xml(); + + diag "Creating a new transient domain"; + diag $xml; + my $dom; + ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + + diag "Destroying the transient guest"; + $dom->destroy; + + diag "Checking that transient domain has gone away"; + ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + + diag "Destroying the transient network"; + $net->destroy; + + diag "Checking that transient network has gone away"; + ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); +} + +# end diff --git a/scripts/networks/380-guest-network-hostdev.t b/scripts/networks/380-guest-network-hostdev.t new file mode 100644 index 0000000..63fa0c9 --- /dev/null +++ b/scripts/networks/380-guest-network-hostdev.t @@ -0,0 +1,82 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/380-guest-network-hostdev.t - guest connect to a hostdev network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to a hostdev +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my ($domain, $bus, $slot, $func) = $tck->get_host_pci_device(); + +SKIP: { + skip "No available PCI device", 4 unless defined $domain; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->bridge("tck"); + $b->forward(mode => "hostdev"); + $b->host_devices([$domain, $bus, $slot, $func]); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + + $b = $tck->generic_domain(name => "tck"); + $b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11"); + $xml = $b->as_xml(); + + diag "Creating a new transient domain"; + diag $xml; + my $dom; + ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + + diag "Destroying the transient guest"; + $dom->destroy; + + diag "Checking that transient domain has gone away"; + ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + + diag "Destroying the transient network"; + $net->destroy; + + diag "Checking that transient network has gone away"; + ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); +} + +# end diff --git a/t/080-network-builder.t b/t/080-network-builder.t index ec2b70c..a99bc63 100644 --- a/t/080-network-builder.t +++ b/t/080-network-builder.t @@ -23,7 +23,7 @@ my $xml = <<EOF; <network> <name>tck</name> <bridge name="virbr0" /> - <forward dev="eth0" /> + <forward dev="eth0"></forward> <ip address="192.168.100.1" netmask="255.255.255.0"> <dhcp> <range start="192.168.100.50" end="192.168.100.70" /> -- 2.19.1

On 11/2/18 11:52 AM, Daniel P. Berrangé wrote:
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- lib/Sys/Virt/TCK.pm | 33 ++++++++ lib/Sys/Virt/TCK/NetworkBuilder.pm | 33 +++++++- scripts/networks/300-guest-network-isolated.t | 82 ++++++++++++++++++ scripts/networks/310-guest-network-nat.t | 83 +++++++++++++++++++ scripts/networks/320-guest-network-route.t | 83 +++++++++++++++++++ scripts/networks/330-guest-network-open.t | 83 +++++++++++++++++++ scripts/networks/340-guest-network-bridge.t | 79 ++++++++++++++++++ scripts/networks/350-guest-network-private.t | 81 ++++++++++++++++++ scripts/networks/360-guest-network-vepa.t | 81 ++++++++++++++++++ .../networks/370-guest-network-passthrough.t | 81 ++++++++++++++++++ scripts/networks/380-guest-network-hostdev.t | 82 ++++++++++++++++++ t/080-network-builder.t | 2 +- 12 files changed, 800 insertions(+), 3 deletions(-) create mode 100644 scripts/networks/300-guest-network-isolated.t create mode 100644 scripts/networks/310-guest-network-nat.t create mode 100644 scripts/networks/320-guest-network-route.t create mode 100644 scripts/networks/330-guest-network-open.t create mode 100644 scripts/networks/340-guest-network-bridge.t create mode 100644 scripts/networks/350-guest-network-private.t create mode 100644 scripts/networks/360-guest-network-vepa.t create mode 100644 scripts/networks/370-guest-network-passthrough.t create mode 100644 scripts/networks/380-guest-network-hostdev.t
You added all these new tests, but forgot that you made the MANIFEST file static/manually edited in commit a140e4f61 back in May, so the new tests don't get installed. Also, the tests don't actually boot up an OS and try to pass traffic; I guess that's something you're counting on someone adding later? :-) (Same comment for adding the proper iptables rules, but we need to consider what to do about that, because what gets added will in the *very near* future be different depending on version of libvirt and/or whether or not firewalld is using nftables). Those last two shouldn't keep you from pushing the patch though (see my list at the end for the few things that do need to be changed before pushing)
diff --git a/lib/Sys/Virt/TCK.pm b/lib/Sys/Virt/TCK.pm index 04244bd..9457836 100644 --- a/lib/Sys/Virt/TCK.pm +++ b/lib/Sys/Virt/TCK.pm @@ -29,6 +29,7 @@ use File::Path qw(mkpath); use File::Spec::Functions qw(catfile catdir rootdir); use Cwd qw(cwd); use LWP::UserAgent; +use IO::Interface::Simple; use IO::Uncompress::Gunzip qw(gunzip); use IO::Uncompress::Bunzip2 qw(bunzip2); use XML::XPath; @@ -1285,6 +1286,38 @@ sub get_ip_from_leases{ }
+sub find_free_ipv4_subnet { + my $index; + + my %used; + + foreach my $iface (IO::Interface::Simple->interfaces()) {
This works to eliminate conflicts with active interfaces, but doesn't take into account any routes that have the same destination address/prefix as the desired network. For example, you may have a static route for 192.168.125.0/25 pointing to another host that has a routed virtual network with that address. If that's the case, the test will fail. I don't have a quick alternative at hand to suggest though, and the likelyhood of a host having a static route that conflicts with the lowest numbered available 192.168.blah.0/24 network is probably pretty low, so I'm going to overlook this :-)
+ if ($iface->netmask eq "255.255.255.0" && + $iface->address =~ /^192.168.(\d+).\d+/) { + $used{"$1"} = 1; + print "Used $1\n"; + } else { + print "Not used ", $iface->address, "\n"; + } + } + + for (my $i = 1; $i < 255; $i++) { + if (!exists $used{"$i"}) { + $index = $i; + last; + } + } + + return () unless defined $index; + + return ( + address => "192.168.$index.1", + netmask => "255.255.255.0", + dhcpstart => "192.168.$index.100", + dhcpend => "192.168.$index.200" + ); +} + sub shutdown_vm_gracefully { my $dom = shift;
diff --git a/lib/Sys/Virt/TCK/NetworkBuilder.pm b/lib/Sys/Virt/TCK/NetworkBuilder.pm index 09ca6b7..ad0cab8 100644 --- a/lib/Sys/Virt/TCK/NetworkBuilder.pm +++ b/lib/Sys/Virt/TCK/NetworkBuilder.pm @@ -61,6 +61,22 @@ sub forward { return $self; }
+sub interfaces { + my $self = shift; + + $self->{interfaces} = [@_]; + + return $self; +} + +sub host_devices { + my $self = shift; + + $self->{host_devices} = [@_]; + + return $self; +} + sub ipaddr { my $self = shift; my $address = shift; @@ -98,8 +114,21 @@ sub as_xml { $w->emptyTag("bridge", %{$self->{bridge}}) if $self->{bridge};
- $w->emptyTag("forward", %{$self->{forward}}) - if exists $self->{forward}; + if (exists $self->{forward}) { + $w->startTag("forward", %{$self->{forward}}); + foreach (@{$self->{interfaces}}) { + $w->emptyTag("interface", dev => $_); + } + foreach (@{$self->{host_devices}}) { + $w->emptyTag("address", + type => "pci", + domain => $_->[0], + bus => $_->[1], + slot => $_->[2], + function => $_->[3]); + } + $w->endTag("forward"); + }
if ($self->{ipaddr}) { $w->startTag("ip", diff --git a/scripts/networks/300-guest-network-isolated.t b/scripts/networks/300-guest-network-isolated.t new file mode 100644 index 0000000..487e864 --- /dev/null +++ b/scripts/networks/300-guest-network-isolated.t @@ -0,0 +1,82 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/300-guest-network-isolated.t - guest connect to isolated network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to an isolated +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my %subnet = Sys::Virt::TCK->find_free_ipv4_subnet(); + +SKIP: { + skip "No available IPv4 subnet", 4 unless defined $subnet{address}; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->bridge("tck"); + $b->ipaddr($subnet{address}, $subnet{netmask}); + $b->dhcp_range($subnet{dhcpstart}, $subnet{dhcpend}); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object");
In the past (so long ago I don't remember the details) there has been different behavior between transient and persistent networks and domains. If we wanted to be pedantic, we could test it both/all ways. It would be overkill to do all the combinations for *every test* though. Since there are multiple tests here doing almost the same thing, we could make one of them with a persistent network/transient domain, one with transient/persistent, etc (or maybe just be sure there's one of each type, not necessarily all combinations)
+ + $b = $tck->generic_domain(name => "tck"); + $b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11"); + $xml = $b->as_xml(); + + diag "Creating a new transient domain"; + diag $xml; + my $dom; + ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + + diag "Destroying the transient guest"; + $dom->destroy; + + diag "Checking that transient domain has gone away"; + ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + + diag "Destroying the transient network"; + $net->destroy; + + diag "Checking that transient network has gone away"; + ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); +} + +# end diff --git a/scripts/networks/310-guest-network-nat.t b/scripts/networks/310-guest-network-nat.t new file mode 100644 index 0000000..fe1a926 --- /dev/null +++ b/scripts/networks/310-guest-network-nat.t @@ -0,0 +1,83 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/310-guest-network-nat.t - guest connect to nat network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to a nat +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my %subnet = Sys::Virt::TCK->find_free_ipv4_subnet(); + +SKIP: { + skip "No available IPv4 subnet", 4 unless defined $subnet{address}; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->bridge("tck"); + $b->forward(mode => "nat"); + $b->ipaddr($subnet{address}, $subnet{netmask}); + $b->dhcp_range($subnet{dhcpstart}, $subnet{dhcpend}); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + + $b = $tck->generic_domain(name => "tck"); + $b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11"); + $xml = $b->as_xml(); + + diag "Creating a new transient domain"; + diag $xml; + my $dom; + ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + + diag "Destroying the transient guest"; + $dom->destroy; + + diag "Checking that transient domain has gone away"; + ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + + diag "Destroying the transient network"; + $net->destroy; + + diag "Checking that transient network has gone away"; + ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); +} + +# end diff --git a/scripts/networks/320-guest-network-route.t b/scripts/networks/320-guest-network-route.t new file mode 100644 index 0000000..91f0b70 --- /dev/null +++ b/scripts/networks/320-guest-network-route.t @@ -0,0 +1,83 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/320-guest-network-route.t - guest connect to routed network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to a routed +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my %subnet = Sys::Virt::TCK->find_free_ipv4_subnet(); + +SKIP: { + skip "No available IPv4 subnet", 4 unless defined $subnet{address}; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->bridge("tck"); + $b->forward(mode => "route"); + $b->ipaddr($subnet{address}, $subnet{netmask}); + $b->dhcp_range($subnet{dhcpstart}, $subnet{dhcpend}); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + + $b = $tck->generic_domain(name => "tck"); + $b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11"); + $xml = $b->as_xml(); + + diag "Creating a new transient domain"; + diag $xml; + my $dom; + ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + + diag "Destroying the transient guest"; + $dom->destroy; + + diag "Checking that transient domain has gone away"; + ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + + diag "Destroying the transient network"; + $net->destroy; + + diag "Checking that transient network has gone away"; + ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); +} + +# end diff --git a/scripts/networks/330-guest-network-open.t b/scripts/networks/330-guest-network-open.t new file mode 100644 index 0000000..113f4cc --- /dev/null +++ b/scripts/networks/330-guest-network-open.t @@ -0,0 +1,83 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/330-guest-network-open.t - guest connect to open network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to an open +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my %subnet = Sys::Virt::TCK->find_free_ipv4_subnet(); + +SKIP: { + skip "No available IPv4 subnet", 4 unless defined $subnet{address}; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->bridge("tck"); + $b->forward(mode => "open"); + $b->ipaddr($subnet{address}, $subnet{netmask}); + $b->dhcp_range($subnet{dhcpstart}, $subnet{dhcpend}); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + + $b = $tck->generic_domain(name => "tck"); + $b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11"); + $xml = $b->as_xml(); + + diag "Creating a new transient domain"; + diag $xml; + my $dom; + ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + + diag "Destroying the transient guest"; + $dom->destroy; + + diag "Checking that transient domain has gone away"; + ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + + diag "Destroying the transient network"; + $net->destroy; + + diag "Checking that transient network has gone away"; + ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); +} + +# end diff --git a/scripts/networks/340-guest-network-bridge.t b/scripts/networks/340-guest-network-bridge.t new file mode 100644 index 0000000..e5db0ff --- /dev/null +++ b/scripts/networks/340-guest-network-bridge.t @@ -0,0 +1,79 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/340-guest-network-bridge.t - guest connect to bridge network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to a bridge +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +((system "brctl addbr tck") == 0) or die "cannot create bridge 'tck'"; + +END { system "brctl delbr tck" } + +my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); +$b->bridge("tck"); +$b->forward(mode => "bridge"); +my $xml = $b->as_xml(); + +diag "Creating a new transient network"; +diag $xml; +my $net; +ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + +$b = $tck->generic_domain(name => "tck"); +$b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11"); +$xml = $b->as_xml(); + +diag "Creating a new transient domain"; +diag $xml; +my $dom; +ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + +diag "Destroying the transient guest"; +$dom->destroy; + +diag "Checking that transient domain has gone away"; +ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + +diag "Destroying the transient network"; +$net->destroy; + +diag "Checking that transient network has gone away"; +ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); + +# end diff --git a/scripts/networks/350-guest-network-private.t b/scripts/networks/350-guest-network-private.t new file mode 100644 index 0000000..0b98149 --- /dev/null +++ b/scripts/networks/350-guest-network-private.t @@ -0,0 +1,81 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/350-guest-network-private.t - guest connect to private network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to a private +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my $hostnet = $tck->get_host_network_device(); + +SKIP: { + skip "No host device available", 4 unless $hostnet; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->forward(mode => "private"); + $b->interfaces($hostnet); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + + $b = $tck->generic_domain(name => "tck"); + $b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11"); + $xml = $b->as_xml(); + + diag "Creating a new transient domain"; + diag $xml; + my $dom; + ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + + diag "Destroying the transient guest"; + $dom->destroy; + + diag "Checking that transient domain has gone away"; + ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + + diag "Destroying the transient network"; + $net->destroy; + + diag "Checking that transient network has gone away"; + ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); +} + +# end diff --git a/scripts/networks/360-guest-network-vepa.t b/scripts/networks/360-guest-network-vepa.t new file mode 100644 index 0000000..f32ad28 --- /dev/null +++ b/scripts/networks/360-guest-network-vepa.t @@ -0,0 +1,81 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/360-guest-network-vepa.t - guest connect to vepa network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to a VEPA +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my $hostnet = $tck->get_host_network_device(); + +SKIP: { + skip "No host device available", 4 unless $hostnet; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->forward(mode => "vepa"); + $b->interfaces($hostnet); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + + $b = $tck->generic_domain(name => "tck"); + $b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11"); + $xml = $b->as_xml(); + + diag "Creating a new transient domain"; + diag $xml; + my $dom; + ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + + diag "Destroying the transient guest"; + $dom->destroy; + + diag "Checking that transient domain has gone away"; + ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + + diag "Destroying the transient network"; + $net->destroy; + + diag "Checking that transient network has gone away"; + ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); +} + +# end diff --git a/scripts/networks/370-guest-network-passthrough.t b/scripts/networks/370-guest-network-passthrough.t new file mode 100644 index 0000000..ebd210d --- /dev/null +++ b/scripts/networks/370-guest-network-passthrough.t @@ -0,0 +1,81 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/370-guest-network-passthrough.t - guest connect to passthrough network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to a passthrough +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my $hostnet = $tck->get_host_network_device(); + +SKIP: { + skip "No host device available", 4 unless $hostnet; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->forward(mode => "passthrough"); + $b->interfaces($hostnet); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + + $b = $tck->generic_domain(name => "tck"); + $b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11"); + $xml = $b->as_xml(); + + diag "Creating a new transient domain"; + diag $xml; + my $dom; + ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + + diag "Destroying the transient guest"; + $dom->destroy; + + diag "Checking that transient domain has gone away"; + ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + + diag "Destroying the transient network"; + $net->destroy; + + diag "Checking that transient network has gone away"; + ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); +} + +# end diff --git a/scripts/networks/380-guest-network-hostdev.t b/scripts/networks/380-guest-network-hostdev.t new file mode 100644 index 0000000..63fa0c9 --- /dev/null +++ b/scripts/networks/380-guest-network-hostdev.t @@ -0,0 +1,82 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/380-guest-network-hostdev.t - guest connect to a hostdev network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to a hostdev +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my ($domain, $bus, $slot, $func) = $tck->get_host_pci_device(); + +SKIP: { + skip "No available PCI device", 4 unless defined $domain; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->bridge("tck");
There shouldn't be a bridge device for a hostdev network. Removing the line above is sufficient.
+ $b->forward(mode => "hostdev");
This should also have 'managed => "yes"' for maximum ease of use (you have to go to the trouble of blacklisting things or explicitly running nodedev-detach to get the VFs pre-detached from the hostside VF net driver).
+ $b->host_devices([$domain, $bus, $slot, $func]); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + + $b = $tck->generic_domain(name => "tck"); + $b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11");
Sigh. (That has nothing to do with this bit of code. I just happened to type it in for some reason while this review email was up on my screen. Probably it was meant for another window, I'm not sure. I was just kind of amused to find it sitting here as I scanned through the message before sending it, so thought I'd leave it in for comic relief).
+ $xml = $b->as_xml(); + + diag "Creating a new transient domain"; + diag $xml; + my $dom; + ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + + diag "Destroying the transient guest"; + $dom->destroy; + + diag "Checking that transient domain has gone away"; + ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + + diag "Destroying the transient network"; + $net->destroy; + + diag "Checking that transient network has gone away"; + ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); +} + +# end diff --git a/t/080-network-builder.t b/t/080-network-builder.t index ec2b70c..a99bc63 100644 --- a/t/080-network-builder.t +++ b/t/080-network-builder.t @@ -23,7 +23,7 @@ my $xml = <<EOF; <network> <name>tck</name> <bridge name="virbr0" /> - <forward dev="eth0" /> + <forward dev="eth0"></forward>
Is the above some odd requirement of the way things are added into existing XML?
<ip address="192.168.100.1" netmask="255.255.255.0"> <dhcp> <range start="192.168.100.50" end="192.168.100.70" />
Assuming the following: * add new test files to MANIFEST * remove $b->bridge("tck") from hostdev test * add 'managed => "yes"' to the $b->forward(...) in hostdev test Tested-by: Laine Stump <laine@laine.org> Reviewed-by: Laine Stump <laine@laine.org> (Yes, I actually added hostdevs and nics to the config file and ran *all* the tests :-)

On Fri, Nov 02, 2018 at 04:23:02PM -0400, Laine Stump wrote:
On 11/2/18 11:52 AM, Daniel P. Berrangé wrote:
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- lib/Sys/Virt/TCK.pm | 33 ++++++++ lib/Sys/Virt/TCK/NetworkBuilder.pm | 33 +++++++- scripts/networks/300-guest-network-isolated.t | 82 ++++++++++++++++++ scripts/networks/310-guest-network-nat.t | 83 +++++++++++++++++++ scripts/networks/320-guest-network-route.t | 83 +++++++++++++++++++ scripts/networks/330-guest-network-open.t | 83 +++++++++++++++++++ scripts/networks/340-guest-network-bridge.t | 79 ++++++++++++++++++ scripts/networks/350-guest-network-private.t | 81 ++++++++++++++++++ scripts/networks/360-guest-network-vepa.t | 81 ++++++++++++++++++ .../networks/370-guest-network-passthrough.t | 81 ++++++++++++++++++ scripts/networks/380-guest-network-hostdev.t | 82 ++++++++++++++++++ t/080-network-builder.t | 2 +- 12 files changed, 800 insertions(+), 3 deletions(-) create mode 100644 scripts/networks/300-guest-network-isolated.t create mode 100644 scripts/networks/310-guest-network-nat.t create mode 100644 scripts/networks/320-guest-network-route.t create mode 100644 scripts/networks/330-guest-network-open.t create mode 100644 scripts/networks/340-guest-network-bridge.t create mode 100644 scripts/networks/350-guest-network-private.t create mode 100644 scripts/networks/360-guest-network-vepa.t create mode 100644 scripts/networks/370-guest-network-passthrough.t create mode 100644 scripts/networks/380-guest-network-hostdev.t
You added all these new tests, but forgot that you made the MANIFEST file static/manually edited in commit a140e4f61 back in May, so the new tests don't get installed.
Hah, forgot that :-)
Also, the tests don't actually boot up an OS and try to pass traffic; I guess that's something you're counting on someone adding later? :-)
I was really only interested in testing the code in libvirtd that connects guests to virtual networks, to exercise code paths i'm refactoring right now. I'll leave testing of guest traffic as an exercise for future contribs.
+sub find_free_ipv4_subnet { + my $index; + + my %used; + + foreach my $iface (IO::Interface::Simple->interfaces()) {
This works to eliminate conflicts with active interfaces, but doesn't take into account any routes that have the same destination address/prefix as the desired network. For example, you may have a static route for 192.168.125.0/25 pointing to another host that has a routed virtual network with that address. If that's the case, the test will fail.
I don't have a quick alternative at hand to suggest though, and the likelyhood of a host having a static route that conflicts with the lowest numbered available 192.168.blah.0/24 network is probably pretty low, so I'm going to overlook this :-)
We could allow for a config file parameter to override this for people how have that scenario.
+ if ($iface->netmask eq "255.255.255.0" && + $iface->address =~ /^192.168.(\d+).\d+/) { + $used{"$1"} = 1; + print "Used $1\n"; + } else { + print "Not used ", $iface->address, "\n"; + } + } + + for (my $i = 1; $i < 255; $i++) { + if (!exists $used{"$i"}) { + $index = $i; + last; + } + } + + return () unless defined $index; + + return ( + address => "192.168.$index.1", + netmask => "255.255.255.0", + dhcpstart => "192.168.$index.100", + dhcpend => "192.168.$index.200" + ); +} +
diff --git a/scripts/networks/300-guest-network-isolated.t b/scripts/networks/300-guest-network-isolated.t new file mode 100644 index 0000000..487e864 --- /dev/null +++ b/scripts/networks/300-guest-network-isolated.t @@ -0,0 +1,82 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/300-guest-network-isolated.t - guest connect to isolated network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to an isolated +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my %subnet = Sys::Virt::TCK->find_free_ipv4_subnet(); + +SKIP: { + skip "No available IPv4 subnet", 4 unless defined $subnet{address}; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->bridge("tck"); + $b->ipaddr($subnet{address}, $subnet{netmask}); + $b->dhcp_range($subnet{dhcpstart}, $subnet{dhcpend}); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object");
In the past (so long ago I don't remember the details) there has been different behavior between transient and persistent networks and domains. If we wanted to be pedantic, we could test it both/all ways. It would be overkill to do all the combinations for *every test* though. Since there are multiple tests here doing almost the same thing, we could make one of them with a persistent network/transient domain, one with transient/persistent, etc (or maybe just be sure there's one of each type, not necessarily all combinations)
For the sake of testing setup of guest NICs with networks, I don't think there's significant difference.
diff --git a/scripts/networks/380-guest-network-hostdev.t b/scripts/networks/380-guest-network-hostdev.t new file mode 100644 index 0000000..63fa0c9 --- /dev/null +++ b/scripts/networks/380-guest-network-hostdev.t @@ -0,0 +1,82 @@ +# -*- perl -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; You can redistribute it and/or modify +# it under the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any +# later version +# +# The file "LICENSE" distributed along with this file provides full +# details of the terms and conditions +# + +=pod + +=head1 NAME + +network/380-guest-network-hostdev.t - guest connect to a hostdev network + +=head1 DESCRIPTION + +This test case validates that a guest is connected to a hostdev +virtual network + +=cut + +use strict; +use warnings; + +use Test::More tests => 4; + +use Sys::Virt::TCK; + +my $tck = Sys::Virt::TCK->new(); +my $conn = eval { $tck->setup(); }; +BAIL_OUT "failed to setup test harness: $@" if $@; +END { $tck->cleanup if $tck; } + +my ($domain, $bus, $slot, $func) = $tck->get_host_pci_device(); + +SKIP: { + skip "No available PCI device", 4 unless defined $domain; + + my $b = Sys::Virt::TCK::NetworkBuilder->new(name => "tck"); + $b->bridge("tck");
There shouldn't be a bridge device for a hostdev network. Removing the line above is sufficient.
+ $b->forward(mode => "hostdev");
This should also have 'managed => "yes"' for maximum ease of use (you have to go to the trouble of blacklisting things or explicitly running nodedev-detach to get the VFs pre-detached from the hostside VF net driver).
Opps, these comments remind me that I never actually tested the hostdev scenario.
+ $b->host_devices([$domain, $bus, $slot, $func]); + my $xml = $b->as_xml(); + + diag "Creating a new transient network"; + diag $xml; + my $net; + ok_network(sub { $net = $conn->create_network($xml) }, "created transient network object"); + + $b = $tck->generic_domain(name => "tck"); + $b->interface(type => "network", + source => "tck", + model => "virtio", + mac => "52:54:00:11:11:11");
Sigh.
(That has nothing to do with this bit of code. I just happened to type it in for some reason while this review email was up on my screen. Probably it was meant for another window, I'm not sure. I was just kind of amused to find it sitting here as I scanned through the message before sending it, so thought I'd leave it in for comic relief).
+ $xml = $b->as_xml(); + + diag "Creating a new transient domain"; + diag $xml; + my $dom; + ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object"); + + diag "Destroying the transient guest"; + $dom->destroy; + + diag "Checking that transient domain has gone away"; + ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain", + Sys::Virt::Error::ERR_NO_DOMAIN); + + diag "Destroying the transient network"; + $net->destroy; + + diag "Checking that transient network has gone away"; + ok_error(sub { $conn->get_network_by_name("tck") }, "NO_network error raised from missing network", + Sys::Virt::Error::ERR_NO_NETWORK); +} + +# end diff --git a/t/080-network-builder.t b/t/080-network-builder.t index ec2b70c..a99bc63 100644 --- a/t/080-network-builder.t +++ b/t/080-network-builder.t @@ -23,7 +23,7 @@ my $xml = <<EOF; <network> <name>tck</name> <bridge name="virbr0" /> - <forward dev="eth0" /> + <forward dev="eth0"></forward>
Is the above some odd requirement of the way things are added into existing XML?
Yeah, the Perl XML generator doesn't omit the tag pair when there's no children.
<ip address="192.168.100.1" netmask="255.255.255.0"> <dhcp> <range start="192.168.100.50" end="192.168.100.70" />
Assuming the following:
* add new test files to MANIFEST * remove $b->bridge("tck") from hostdev test * add 'managed => "yes"' to the $b->forward(...) in hostdev test
Tested-by: Laine Stump <laine@laine.org>
Reviewed-by: Laine Stump <laine@laine.org>
(Yes, I actually added hostdevs and nics to the config file and ran *all* the tests :-)
pub 2048R/0xC4F5579A8DA0E3E5 2018-11-01 Laine Stump <laine@laine.org> sub 2048R/0x92B8139F103E1242 2018-11-01 [expires: 2019-11-01]
Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

The code does not in fact delete everything on the host, only things whose name starts with a "tck" prefix. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- bin/libvirt-tck | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/bin/libvirt-tck b/bin/libvirt-tck index 816234b..d5519dd 100644 --- a/bin/libvirt-tck +++ b/bin/libvirt-tck @@ -38,20 +38,22 @@ test suite for libvirt drivers. =head2 WARNING -There now follows a few words of warning +The test suite is intended to be moderately safe to run on arbitrary +hosts and takes steps to avoid intentionally breaking things. -The test suite needs to have a completely 'clean' initial -starting state. If your host already has virtual machines -defined and/or running this will cause problems. The test -suite will detect this and refuse to run, allowing you to -remove any preexisting guests. Alternatively you can pass -the --force option and libvirt will DELETE EVERYTHING it -finds. +All objects (guests, networks, storage pools, etc) that are created +will have a name prefix of "tck" to minimize risk of clashes. The +test suite will only ever (intentionally) delete objects with a +"tck" name prefix. -To repeat: ALL YOUR EXISTING DOMAINS, NETWORKS, STORAGE POOLS -WILL BE DELETED IF YOU USE THE --force OPTION. +Where a test suite needs access to a precious host resource (physical +NIC, PCI device, USB device, block device), execution will be skipped +until the admin has white listed one or more suitable resources in +the C</etc/libvirt-tck/default.cfg> configuration file. -The warning is now complete, continue reading +Despite these precautions, running automated tests always carries some +degree of risk to the host system. It is thus advisable to avoid +executing this test suite on hosts with precious state. =head2 OPTIONS @@ -90,13 +92,11 @@ C<xml> option generates a formal XML document of results. =item --force -Forcably remove all running guest domains and all persistent guest -domain configuration files before running any tests. The test suite -requires a pristine install, so all existing managed objects must -be removed before running. This switch will instruct libvirt-tck -to automatically remove all guest domains. YOU WILL NOT GET YOUR -EXISTING GUEST DOMAINS BACK IF THIS HAPPENS. THEY WILL BE GONE -FOREVER. USE AT YOUR OWN RISK. +Forcably remove all previously created objects, including guests, +networks, storage pools, etc which have a "tck" name prefix. + +User created objects whose name does not start with "tck" will be +left untouched. =item -t, --testdir PATH -- 2.19.1

On 11/2/18 11:52 AM, Daniel P. Berrangé wrote:
The code does not in fact delete everything on the host, only things whose name starts with a "tck" prefix.
Yep! Multiple people have asked me about that, and I had to allay their fears (I was actually worried about it for a long time, then one day realized that I'd accidentally run the tck on a host with lots of guests/networks, and "surprise!" nothing bad happened :-) Reviewed-by: Laine Stump <laine@laine.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- bin/libvirt-tck | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/bin/libvirt-tck b/bin/libvirt-tck index 816234b..d5519dd 100644 --- a/bin/libvirt-tck +++ b/bin/libvirt-tck @@ -38,20 +38,22 @@ test suite for libvirt drivers.
=head2 WARNING
-There now follows a few words of warning +The test suite is intended to be moderately safe to run on arbitrary +hosts and takes steps to avoid intentionally breaking things.
-The test suite needs to have a completely 'clean' initial -starting state. If your host already has virtual machines -defined and/or running this will cause problems. The test -suite will detect this and refuse to run, allowing you to -remove any preexisting guests. Alternatively you can pass -the --force option and libvirt will DELETE EVERYTHING it -finds. +All objects (guests, networks, storage pools, etc) that are created +will have a name prefix of "tck" to minimize risk of clashes. The +test suite will only ever (intentionally) delete objects with a +"tck" name prefix.
-To repeat: ALL YOUR EXISTING DOMAINS, NETWORKS, STORAGE POOLS -WILL BE DELETED IF YOU USE THE --force OPTION. +Where a test suite needs access to a precious host resource (physical +NIC, PCI device, USB device, block device), execution will be skipped +until the admin has white listed one or more suitable resources in +the C</etc/libvirt-tck/default.cfg> configuration file.
-The warning is now complete, continue reading +Despite these precautions, running automated tests always carries some +degree of risk to the host system. It is thus advisable to avoid +executing this test suite on hosts with precious state.
=head2 OPTIONS
@@ -90,13 +92,11 @@ C<xml> option generates a formal XML document of results.
=item --force
-Forcably remove all running guest domains and all persistent guest -domain configuration files before running any tests. The test suite -requires a pristine install, so all existing managed objects must -be removed before running. This switch will instruct libvirt-tck -to automatically remove all guest domains. YOU WILL NOT GET YOUR -EXISTING GUEST DOMAINS BACK IF THIS HAPPENS. THEY WILL BE GONE -FOREVER. USE AT YOUR OWN RISK. +Forcably remove all previously created objects, including guests, +networks, storage pools, etc which have a "tck" name prefix. + +User created objects whose name does not start with "tck" will be +left untouched.
=item -t, --testdir PATH

The -t argument accepts the path to a test file or a test directory. It would be useful if shell wildcards could be used to specify test files, but this doesn't work when using optional arguments. By changing the test path(s) to be positional arguments we can easily allow for shell wildcards. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- bin/libvirt-tck | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/bin/libvirt-tck b/bin/libvirt-tck index d5519dd..bd332a4 100644 --- a/bin/libvirt-tck +++ b/bin/libvirt-tck @@ -8,7 +8,7 @@ libvirt-tck - libvirt Technology Compatability Kit =head1 SYNOPSIS - # libvirt-tck [OPTIONS] + # libvirt-tck [OPTIONS] [TESTS..] Run with default config, probing for URI to use @@ -62,8 +62,15 @@ the default configuration file from C</etc/libvirt-tck/default.cfg> and will allow libvirt to probe for the hypervisor driver to run. If a reliably repeatable test result set is desired, it is recommended to always give an explicit libvirt connection URI -to choose the driver. The following options are available when -running the C<libvirt-tck> command +to choose the driver. + +Any command line arguments that are not parsed as options will +be considered paths to test scripts to invoke. If no paths are +given, all tests under C</usr/share/libvirt-tck/tests> will be +executed. + +The following options are available when running the C<libvirt-tck> +command =over 4 @@ -98,11 +105,6 @@ networks, storage pools, etc which have a "tck" name prefix. User created objects whose name does not start with "tck" will be left untouched. -=item -t, --testdir PATH - -Specify an alternate directory path in which to find the test -scripts to be run. If omitted, defaults to C</usr/share/libvirt-tck/tests> - =item -a, --archive FILE Generate an archive containing all the raw test results. The @@ -144,7 +146,6 @@ my $timer = 0; my $archive; my $config = catfile($confdir, "default.cfg"); my $format = "text"; -my $testdir = catdir($datadir, "tests"); if (!GetOptions("verbose" => \$verbose, "debug" => \$debug, @@ -154,7 +155,6 @@ if (!GetOptions("verbose" => \$verbose, "config=s" => \$config, "force" => \$force, "format=s" => \$format, - "testdir=s" => \$testdir, "timer" => \$timer) || $help) { pod2usage(-verbose => $help, -output => $help ? \*STDOUT : \*STDERR, @@ -181,12 +181,19 @@ if ($verbose && $quiet) { -output => \*STDERR); } -unless (-e $testdir) { - print STDERR "$0: test directory '$testdir' does not exist\n"; - exit 2; +my @testdirs = @ARGV; +unless (@testdirs) { + push @testdirs, catdir($datadir, "tests"); +} + +foreach (@testdirs) { + unless (-e $_) { + print STDERR "$0: test path '$_' does not exist\n"; + exit 2; + } } -my @newargv = ("-r", "--norc", "--merge", $testdir); +my @newargv = ("-r", "--norc", "--merge", @testdirs); if ($archive) { push @newargv, "-a", $archive; -- 2.19.1

On 11/2/18 11:52 AM, Daniel P. Berrangé wrote:
The -t argument accepts the path to a test file or a test directory. It would be useful if shell wildcards could be used to specify test files, but this doesn't work when using optional arguments.
By changing the test path(s) to be positional arguments we can easily allow for shell wildcards.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
I don't have experience with whatever is doing the commandline parsing, but it looks like it ought to work, and the few things I threw at it worked as expected. Reviewed-by: Laine Stump <laine@laine.org>
--- bin/libvirt-tck | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-)
diff --git a/bin/libvirt-tck b/bin/libvirt-tck index d5519dd..bd332a4 100644 --- a/bin/libvirt-tck +++ b/bin/libvirt-tck @@ -8,7 +8,7 @@ libvirt-tck - libvirt Technology Compatability Kit
=head1 SYNOPSIS
- # libvirt-tck [OPTIONS] + # libvirt-tck [OPTIONS] [TESTS..]
Run with default config, probing for URI to use
@@ -62,8 +62,15 @@ the default configuration file from C</etc/libvirt-tck/default.cfg> and will allow libvirt to probe for the hypervisor driver to run. If a reliably repeatable test result set is desired, it is recommended to always give an explicit libvirt connection URI -to choose the driver. The following options are available when -running the C<libvirt-tck> command +to choose the driver. + +Any command line arguments that are not parsed as options will +be considered paths to test scripts to invoke. If no paths are +given, all tests under C</usr/share/libvirt-tck/tests> will be +executed. + +The following options are available when running the C<libvirt-tck> +command
=over 4
@@ -98,11 +105,6 @@ networks, storage pools, etc which have a "tck" name prefix. User created objects whose name does not start with "tck" will be left untouched.
-=item -t, --testdir PATH - -Specify an alternate directory path in which to find the test -scripts to be run. If omitted, defaults to C</usr/share/libvirt-tck/tests> - =item -a, --archive FILE
Generate an archive containing all the raw test results. The @@ -144,7 +146,6 @@ my $timer = 0; my $archive; my $config = catfile($confdir, "default.cfg"); my $format = "text"; -my $testdir = catdir($datadir, "tests");
if (!GetOptions("verbose" => \$verbose, "debug" => \$debug, @@ -154,7 +155,6 @@ if (!GetOptions("verbose" => \$verbose, "config=s" => \$config, "force" => \$force, "format=s" => \$format, - "testdir=s" => \$testdir, "timer" => \$timer) || $help) { pod2usage(-verbose => $help, -output => $help ? \*STDOUT : \*STDERR, @@ -181,12 +181,19 @@ if ($verbose && $quiet) { -output => \*STDERR); }
-unless (-e $testdir) { - print STDERR "$0: test directory '$testdir' does not exist\n"; - exit 2; +my @testdirs = @ARGV; +unless (@testdirs) { + push @testdirs, catdir($datadir, "tests"); +} + +foreach (@testdirs) { + unless (-e $_) { + print STDERR "$0: test path '$_' does not exist\n"; + exit 2; + } }
-my @newargv = ("-r", "--norc", "--merge", $testdir); +my @newargv = ("-r", "--norc", "--merge", @testdirs);
if ($archive) { push @newargv, "-a", $archive;
participants (2)
-
Daniel P. Berrangé
-
Laine Stump