ci: Add OVS-DPDK integration test

In order to avoid regression regarding OVS-DPDK support, a new
integration test is added. This test consists of running two VMs, both
attached to a distinct OVS port, where both ports are connected to an
OVS bridge. Once the VM are running, the test validates the connection
between the two VMs works correctly.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2021-05-27 14:55:57 +02:00
parent 239e2adc68
commit 4db7530f28
4 changed files with 141 additions and 2 deletions

3
Jenkinsfile vendored
View File

@ -46,6 +46,7 @@ pipeline{
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "sudo modprobe openvswitch"
sh "scripts/dev_cli.sh tests --integration"
}
}
@ -69,6 +70,7 @@ pipeline{
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "sudo modprobe openvswitch"
sh "scripts/dev_cli.sh tests --integration"
}
}
@ -98,6 +100,7 @@ pipeline{
timeout(time: 1, unit: 'HOURS')
}
steps {
sh "sudo modprobe openvswitch"
sh "scripts/dev_cli.sh tests --integration --libc musl"
}
}

View File

@ -227,6 +227,13 @@ sudo bash -c "echo 1000000 > /sys/kernel/mm/ksm/pages_to_scan"
sudo bash -c "echo 10 > /sys/kernel/mm/ksm/sleep_millisecs"
sudo bash -c "echo 1 > /sys/kernel/mm/ksm/run"
# Setup ovs-dpdk
echo 2048 | sudo tee /proc/sys/vm/nr_hugepages
service openvswitch-switch start
ovs-vsctl init
ovs-vsctl set Open_vSwitch . other_config:dpdk-init=true
service openvswitch-switch restart
time cargo test $features_test_fdt "tests::parallel::$test_filter"
RES=$?
echo "Integration test on FDT finished with result $RES."

View File

@ -198,10 +198,16 @@ sudo bash -c "echo 1000000 > /sys/kernel/mm/ksm/pages_to_scan"
sudo bash -c "echo 10 > /sys/kernel/mm/ksm/sleep_millisecs"
sudo bash -c "echo 1 > /sys/kernel/mm/ksm/run"
# test_vfio relies on hugepages
echo 4096 | sudo tee /proc/sys/vm/nr_hugepages
# Both test_vfio and ovs-dpdk rely on hugepages
echo 6144 | sudo tee /proc/sys/vm/nr_hugepages
sudo chmod a+rwX /dev/hugepages
# Setup ovs-dpdk
service openvswitch-switch start
ovs-vsctl init
ovs-vsctl set Open_vSwitch . other_config:dpdk-init=true
service openvswitch-switch restart
export RUST_BACKTRACE=1
time cargo test $features_test "tests::parallel::$test_filter"
RES=$?

View File

@ -5255,6 +5255,129 @@ mod tests {
handle_child_output(r, &output);
}
#[test]
fn test_ovs_dpdk() {
// Create OVS-DPDK bridge and ports
std::process::Command::new("bash")
.args(&[
"-c",
"ovs-vsctl add-br ovsbr0 -- set bridge ovsbr0 datapath_type=netdev",
])
.status()
.expect("Expected 'ovs-vsctl add-br ovsbr0 -- set bridge ovsbr0 datapath_type=netdev' to work");
std::process::Command::new("bash")
.args(&[
"-c",
"ovs-vsctl add-port ovsbr0 vhost-user1 -- set Interface vhost-user1 type=dpdkvhostuser",
])
.status()
.expect("Expected 'ovs-vsctl add-port ovsbr0 vhost-user1 -- set Interface vhost-user1 type=dpdkvhostuser' to work");
std::process::Command::new("bash")
.args(&[
"-c",
"ovs-vsctl add-port ovsbr0 vhost-user2 -- set Interface vhost-user2 type=dpdkvhostuser",
])
.status()
.expect("Expected 'ovs-vsctl add-port ovsbr0 vhost-user2 -- set Interface vhost-user2 type=dpdkvhostuser' to work");
std::process::Command::new("bash")
.args(&["-c", "ip link set up dev ovsbr0"])
.status()
.expect("Expected 'ip link set up dev ovsbr0' to work");
std::process::Command::new("bash")
.args(&["-c", "service openvswitch-switch restart"])
.status()
.expect("Expected 'service openvswitch-switch restart' to work");
let focal1 = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest1 = Guest::new(Box::new(focal1));
let mut child1 = GuestCommand::new(&guest1)
.args(&["--cpus", "boot=2"])
.args(&["--memory", "size=1G,shared=on"])
.args(&["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(&["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
.default_disks()
.args(&["--net", guest1.default_net_string().as_str(), "vhost_user=true,socket=/var/run/openvswitch/vhost-user1,num_queues=2,queue_size=256,vhost_mode=client"])
.capture_output()
.spawn()
.unwrap();
#[cfg(target_arch = "x86_64")]
let guest_net_iface = "ens5";
#[cfg(target_arch = "aarch64")]
let guest_net_iface = "enp0s5";
let r = std::panic::catch_unwind(|| {
guest1.wait_vm_boot(None).unwrap();
assert!(guest1
.ssh_command_ok(&format!(
"sudo ip addr add 172.100.0.1/24 dev {}",
guest_net_iface
))
.unwrap());
assert!(guest1
.ssh_command_ok(&format!("sudo ip link set up dev {}", guest_net_iface))
.unwrap());
let guest_ip = guest1.network.guest_ip.clone();
thread::spawn(move || {
ssh_command_ip(
"iperf3 -s -p 4444",
&guest_ip,
DEFAULT_SSH_RETRIES,
DEFAULT_SSH_TIMEOUT,
)
.unwrap();
});
});
if r.is_err() {
let _ = child1.kill();
let output = child1.wait_with_output().unwrap();
handle_child_output(r, &output);
panic!("Test should already be failed/panicked"); // To explicitly mark this block never return
}
let focal2 = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest2 = Guest::new(Box::new(focal2));
let mut child2 = GuestCommand::new(&guest2)
.args(&["--cpus", "boot=2"])
.args(&["--memory", "size=1G,shared=on"])
.args(&["--kernel", direct_kernel_boot_path().to_str().unwrap()])
.args(&["--cmdline", DIRECT_KERNEL_BOOT_CMDLINE])
.default_disks()
.args(&["--net", guest2.default_net_string().as_str(), "vhost_user=true,socket=/var/run/openvswitch/vhost-user2,num_queues=2,queue_size=256,vhost_mode=client"])
.capture_output()
.spawn()
.unwrap();
let r = std::panic::catch_unwind(|| {
guest2.wait_vm_boot(None).unwrap();
assert!(guest2
.ssh_command_ok(&format!(
"sudo ip addr add 172.100.0.2/24 dev {}",
guest_net_iface
))
.unwrap());
assert!(guest2
.ssh_command_ok(&format!("sudo ip link set up dev {}", guest_net_iface))
.unwrap());
// Check the connection works properly between the two VMs
assert!(guest2
.ssh_command_ok("iperf3 -c 172.100.0.1 -t 10 -p 4444")
.unwrap());
});
let _ = child1.kill();
let _ = child2.kill();
let output = child1.wait_with_output().unwrap();
child2.wait().unwrap();
handle_child_output(r, &output);
}
}
mod sequential {