mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-03 03:15:20 +00:00
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:
parent
239e2adc68
commit
4db7530f28
3
Jenkinsfile
vendored
3
Jenkinsfile
vendored
@ -46,6 +46,7 @@ pipeline{
|
|||||||
timeout(time: 1, unit: 'HOURS')
|
timeout(time: 1, unit: 'HOURS')
|
||||||
}
|
}
|
||||||
steps {
|
steps {
|
||||||
|
sh "sudo modprobe openvswitch"
|
||||||
sh "scripts/dev_cli.sh tests --integration"
|
sh "scripts/dev_cli.sh tests --integration"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,6 +70,7 @@ pipeline{
|
|||||||
timeout(time: 1, unit: 'HOURS')
|
timeout(time: 1, unit: 'HOURS')
|
||||||
}
|
}
|
||||||
steps {
|
steps {
|
||||||
|
sh "sudo modprobe openvswitch"
|
||||||
sh "scripts/dev_cli.sh tests --integration"
|
sh "scripts/dev_cli.sh tests --integration"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,6 +100,7 @@ pipeline{
|
|||||||
timeout(time: 1, unit: 'HOURS')
|
timeout(time: 1, unit: 'HOURS')
|
||||||
}
|
}
|
||||||
steps {
|
steps {
|
||||||
|
sh "sudo modprobe openvswitch"
|
||||||
sh "scripts/dev_cli.sh tests --integration --libc musl"
|
sh "scripts/dev_cli.sh tests --integration --libc musl"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 10 > /sys/kernel/mm/ksm/sleep_millisecs"
|
||||||
sudo bash -c "echo 1 > /sys/kernel/mm/ksm/run"
|
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"
|
time cargo test $features_test_fdt "tests::parallel::$test_filter"
|
||||||
RES=$?
|
RES=$?
|
||||||
echo "Integration test on FDT finished with result $RES."
|
echo "Integration test on FDT finished with result $RES."
|
||||||
|
@ -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 10 > /sys/kernel/mm/ksm/sleep_millisecs"
|
||||||
sudo bash -c "echo 1 > /sys/kernel/mm/ksm/run"
|
sudo bash -c "echo 1 > /sys/kernel/mm/ksm/run"
|
||||||
|
|
||||||
# test_vfio relies on hugepages
|
# Both test_vfio and ovs-dpdk rely on hugepages
|
||||||
echo 4096 | sudo tee /proc/sys/vm/nr_hugepages
|
echo 6144 | sudo tee /proc/sys/vm/nr_hugepages
|
||||||
sudo chmod a+rwX /dev/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
|
export RUST_BACKTRACE=1
|
||||||
time cargo test $features_test "tests::parallel::$test_filter"
|
time cargo test $features_test "tests::parallel::$test_filter"
|
||||||
RES=$?
|
RES=$?
|
||||||
|
@ -5255,6 +5255,129 @@ mod tests {
|
|||||||
|
|
||||||
handle_child_output(r, &output);
|
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 {
|
mod sequential {
|
||||||
|
Loading…
Reference in New Issue
Block a user