Guide 7. Linking up virtual machines

What you're going to learn

In this guide you're going to learn:

  1. How to operate multiple virtual machines in a single test.
  2. plug/unplug nic actions.
  3. Some additional nic subattributes.
  4. More information about virtual networks.

Preconditions

  1. Testo Framework is installed.
  2. Virt manager is installed.
  3. Host has the Internet access.
  4. Ubuntu server 16.04 image is downloaded and located here: /opt/iso/ubuntu_server.iso. The location may be different, but in this case the ISO_DIR command-line param has to be adjusted accordingly.
  5. Testo guest additions iso image is downloaded and located in the same folder as Ubuntu Server 16.04 iso-image.
  6. (Recommended) Testo-lang syntax highlight for Sublime Text 3 is set up.
  7. (Recommended) Guide 6 is complete.

Introduction

In the last guide we learned about the virtual networks nat mode, which allows you to provide the Internet access to virtual machines. But, obviously, virtual networks could (and should) be used for linking up virtual machines with each other as well. That's what we're going to do in this guide. Additionally we'll discover a few little tricks to make our test scripts more convenient and easier to read.

At the end of this guide we're going to get the following test bench:

What to begin with?

From this moment on, there will be two virtual machines in our test cases, playing the roles of a server and a client. To make our test scripts more transparent and easier to read, we will need to do some job:

  1. Rename the virtual machine my_ubuntu into server;
  2. Rename the params hostname, login, password into server_hostname, server_login and default_password respectively and adjust all the references to these params;
  3. Rename the tests ubuntu_installation and guest_additions_installation into server_install_ubuntu and server_install_guest_additions respectively;
  4. Delete the test guest_additions_demo.

You should get the following script:

network internet {
	mode: "nat"
}

machine server {
	cpus: 1
	ram: 512Mb
	disk main: {
		size: 5Gb
	}
	iso: "${ISO_DIR}/ubuntu_server.iso"

	nic nat: {
		attached_to: "internet"
	}
}

param server_hostname "server"
param server_login "server-login"
param default_password "1111"

test server_install_ubuntu {
	server {
		start
		wait "English"
		press Enter
		# The actions can be separated with a newline
		# or a semicolon
		wait "Install Ubuntu Server"; press Enter;
		wait "Choose the language";	press Enter
		wait "Select your location"; press Enter
		wait "Detect keyboard layout?";	press Enter
		wait "Country of origin for the keyboard"; press Enter
		wait "Keyboard layout"; press Enter
		#wait "No network interfaces detected" timeout 5m; press Enter
		wait "Hostname:" timeout 5m; press Backspace*36; type "${server_hostname}"; press Enter
		wait "Full name for the new user"; type "${server_login}"; press Enter
		wait "Username for your account"; press Enter
		wait "Choose a password for the new user"; type "${default_password}"; press Enter
		wait "Re-enter password to verify"; type "${default_password}"; press Enter
		wait "Use weak password?"; press Left, Enter
		wait "Encrypt your home directory?"; press Enter

		#wait "Select your timezone" timeout 2m; press Enter
		wait "Is this time zone correct?" timeout 2m; press Enter
		wait "Partitioning method"; press Enter
		wait "Select disk to partition"; press Enter
		wait "Write the changes to disks and configure LVM?"; press Left, Enter
		wait "Amount of volume group to use for guided partitioning"; press Enter
		wait "Write the changes to disks?"; press Left, Enter
		wait "HTTP proxy information" timeout 3m; press Enter
		wait "How do you want to manage upgrades" timeout 6m; press Enter
		wait "Choose software to install"; press Enter
		wait "Install the GRUB boot loader to the master boot record?" timeout 10m; press Enter
		wait "Installation complete" timeout 1m;

		unplug dvd; press Enter
		wait "server_login:" timeout 2m; type "${server_login}"; press Enter
		wait "Password:"; type "${default_password}"; press Enter
		wait "Welcome to Ubuntu"
	}
}

param guest_additions_pkg "testo-guest-additions*"
test server_install_guest_additions: server_install_ubuntu {
	server {
		plug dvd "${ISO_DIR}/testo-guest-additions.iso"

		type "sudo su"; press Enter;
		# Take a note that you may reference params in any part of the string
		wait "password for ${server_login}"; type "${default_password}"; press Enter
		wait "root@${server_hostname}"

		type "mount /dev/cdrom /media"; press Enter
		wait "mounting read-only"; type "dpkg -i /media/${guest_additions_pkg}"; press Enter;
		wait "Setting up testo-guest-additions"
		type "umount /media"; press Enter;
		# Give a little time for the umount to do its job
		sleep 2s
		unplug dvd
	}
}

Since we've renamed our virtual machine into server, Testo treats is as a brand new machine, therefore all the tests must run again, including the virtual machine creation.

But we need to keep in mind that the old virtual machine, my_ubuntu, wouldn't go anywhere automatically. Testo Framework "thinks" that this virtual machine may be of some use for you in the future, and thus shouldn't be removed. Still, we, as humans, understand that we won't need my_ubuntu anymore, so let's delete it:

user$ sudo testo clean
Testo is about to erase the following entities:
Virtual networks:
- internet
Virtual machines:
- my_ubuntu

Do you confirm erasing these entities? [y/N]: y
Deleted network internet
Deleted virtual machine my_ubuntu
user$

You can see that the virtual network internet was deleted as well.

Now, before doing anything else, it's good to make sure we didn't break anything with our changes.

user$ sudo testo run hello_world.testo --stop_on_fail --param ISO_DIR /opt/iso
TESTS TO RUN:
server_install_ubuntu
server_install_guest_additions
[ 0%] Preparing the environment for test server_install_ubuntu
[ 0%] Restoring snapshot initial for virtual machine server
[ 0%] Running test server_install_ubuntu
[ 0%] Starting virtual machine server
[ 0%] Waiting English for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Install Ubuntu Server for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Choose the language for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Select your location for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Detect keyboard layout? for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Country of origin for the keyboard for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Keyboard layout for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Hostname: for 5m with interval 1s in virtual machine server
[ 0%] Pressing key BACKSPACE 36 times on virtual machine server
[ 0%] Typing "server" with interval 30ms in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Full name for the new user for 1m with interval 1s in virtual machine server
[ 0%] Typing "server-login" with interval 30ms in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Username for your account for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Choose a password for the new user for 1m with interval 1s in virtual machine server
[ 0%] Typing "1111" with interval 30ms in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Re-enter password to verify for 1m with interval 1s in virtual machine server
[ 0%] Typing "1111" with interval 30ms in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Use weak password? for 1m with interval 1s in virtual machine server
[ 0%] Pressing key LEFT on virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Encrypt your home directory? for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Is this time zone correct? for 2m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Partitioning method for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Select disk to partition for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Write the changes to disks and configure LVM? for 1m with interval 1s in virtual machine server
[ 0%] Pressing key LEFT on virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Amount of volume group to use for guided partitioning for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Write the changes to disks? for 1m with interval 1s in virtual machine server
[ 0%] Pressing key LEFT on virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting HTTP proxy information for 3m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting How do you want to manage upgrades for 6m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Choose software to install for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Install the GRUB boot loader to the master boot record? for 10m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Installation complete for 1m with interval 1s in virtual machine server
[ 0%] Unplugging dvd from virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting server login: for 2m with interval 1s in virtual machine server
[ 0%] Typing "server-login" with interval 30ms in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Password: for 1m with interval 1s in virtual machine server
[ 0%] Typing "1111" with interval 30ms in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Welcome to Ubuntu for 1m with interval 1s in virtual machine server
[ 0%] Taking snapshot server_install_ubuntu for virtual machine server
[ 50%] Test server_install_ubuntu PASSED in 0h:5m:35s
[ 50%] Preparing the environment for test server_install_guest_additions
[ 50%] Running test server_install_guest_additions
[ 50%] Plugging dvd /opt/iso/testo-guest-additions.iso into virtual machine server
[ 50%] Typing "sudo su" with interval 30ms in virtual machine server
[ 50%] Pressing key ENTER on virtual machine server
[ 50%] Waiting password for server-login for 1m with interval 1s in virtual machine server
[ 50%] Typing "1111" with interval 30ms in virtual machine server
[ 50%] Pressing key ENTER on virtual machine server
[ 50%] Waiting root@server for 1m with interval 1s in virtual machine server
[ 50%] Typing "mount /dev/cdrom /media" with interval 30ms in virtual machine server
[ 50%] Pressing key ENTER on virtual machine server
[ 50%] Waiting mounting read-only for 1m with interval 1s in virtual machine server
[ 50%] Typing "dpkg -i /media/testo-guest-additions*" with interval 30ms in virtual machine server
[ 50%] Pressing key ENTER on virtual machine server
[ 50%] Waiting Setting up testo-guest-additions for 1m with interval 1s in virtual machine server
[ 50%] Typing "umount /media" with interval 30ms in virtual machine server
[ 50%] Pressing key ENTER on virtual machine server
[ 50%] Sleeping in virtual machine server for 2s
[ 50%] Unplugging dvd from virtual machine server
[ 50%] Taking snapshot server_install_guest_additions for virtual machine server
[100%] Test server_install_guest_additions PASSED in 0h:0m:15s
PROCESSED TOTAL 2 TESTS IN 0h:5m:51s
UP-TO-DATE: 0
RUN SUCCESSFULLY: 2
FAILED: 0
user$

Declaring the second virtual machine

Now it's time to declare our second virtual machine. As you've probably guessed, it's going to be named client, and will be mostly a copy of the server machine.

machine client {
    cpus: 1
    ram: 512Mb
    disk main: {
        size: 5Gb
    }
    iso: "${ISO_DIR}/ubuntu_server.iso"

    nic nat: {
        attached_to: "internet"
    }
}

But if we leave our virtual machines as they are now, they won't be connected in any way. To link them up we need to declare a new virtual network:

network LAN {
    mode: "internal"
}

Take a note that this network is declared as internal, which means that it's designated to isolated connection between machines.

All that's left to do is to add new NICs to the virtual machines, with attachment to the LAN network:

machine client {
    cpus: 1
    ram: 512Mb
    disk main: {
        size: 5Gb
    }
    iso: "${ISO_DIR}/ubuntu_server.iso"

    nic nat: {
        attached_to: "internet"
    }

    nic server_side: {
        attached_to: "LAN"
        mac: "52:54:00:00:00:AA"
    }
}

machine server {
    cpus: 1
    ram: 512Mb
    disk main: {
        size: 5Gb
    }
    iso: "${ISO_DIR}/ubuntu_server.iso"

    nic nat: {
        attached_to: "internet"
    }

    nic client_side: {
        attached_to: "LAN"
        mac: "52:54:00:00:00:BB"
    }
}

You can see that we added the mac subattribute to the "internal" NICs. Knowing the exact mac will play its role a little later, when we'll do renaming NICs inside the OS (so we can distinguish them easily).

Of course, the new client machine needs a couple of preparatory tests of its own: client_install_ubuntu and client_install_guest_additions. Don't forget to add a couple of new params:

param client_hostname "client"
param client_login "client-login"

test client_install_ubuntu {
    client {
        start
        wait "English"
        press Enter
        # The actions can be separated with a newline
        # or a semicolon
        wait "Install Ubuntu Server"; press Enter;
        wait "Choose the language"; press Enter
        wait "Select your location"; press Enter
        wait "Detect keyboard layout?"; press Enter
        wait "Country of origin for the keyboard"; press Enter
        wait "Keyboard layout"; press Enter
        #wait "No network interfaces detected" timeout 5m; press Enter
        wait "Hostname:" timeout 5m; press Backspace*36; type "${client_hostname}"; press Enter
        wait "Full name for the new user"; type "${client_login}"; press Enter
        wait "Username for your account"; press Enter
        wait "Choose a password for the new user"; type "${default_password}"; press Enter
        wait "Re-enter password to verify"; type "${default_password}"; press Enter
        wait "Use weak password?"; press Left, Enter
        wait "Encrypt your home directory?"; press Enter

        #wait "Select your timezone" timeout 2m; press Enter
        wait "Is this time zone correct?" timeout 2m; press Enter
        wait "Partitioning method"; press Enter
        wait "Select disk to partition"; press Enter
        wait "Write the changes to disks and configure LVM?"; press Left, Enter
        wait "Amount of volume group to use for guided partitioning"; press Enter
        wait "Write the changes to disks?"; press Left, Enter
        wait "HTTP proxy information" timeout 3m; press Enter
        wait "How do you want to manage upgrades" timeout 6m; press Enter
        wait "Choose software to install"; press Enter
        wait "Install the GRUB boot loader to the master boot record?" timeout 10m; press Enter
        wait "Installation complete" timeout 1m;

        unplug dvd; press Enter
        wait "${client_hostname} login:" timeout 2m; type "${client_login}"; press Enter
        wait "Password:"; type "${default_password}"; press Enter
        wait "Welcome to Ubuntu"
    }
}

test client_install_guest_additions: client_install_ubuntu {
    client {
        plug dvd "${ISO_DIR}/testo-guest-additions.iso"

        type "sudo su"; press Enter;
        # Take a note that you may reference params in any part of the string
        wait "password for ${client_login}"; type "${default_password}"; press Enter
        wait "root@${client_hostname}"

        type "mount /dev/cdrom /media"; press Enter
        wait "mounting read-only"; type "dpkg -i /media/${guest_additions_pkg}"; press Enter;
        wait "Setting up testo-guest-additions"
        type "umount /media"; press Enter;
        # Give a little time for the umount to do its job
        sleep 2s
        unplug dvd
    }
}

We can see a lot of duplicated code, but we shouldn't fret about that. Later we'll learn about macros, which allow to group up frequently-used actions into named blocks, and our sript will get much shorter.

Now let's run our script.

user$ sudo testo run hello_world.testo --stop_on_fail --param ISO_DIR /opt/iso
Because of the cache loss, Testo is scheduled to run the following tests:
- server_install_ubuntu
- server_install_guest_additions
Do you confirm running them? [y/N]: y
TESTS TO RUN:
server_install_ubuntu
server_install_guest_additions
client_install_ubuntu
client_install_guest_additions
[ 0%] Preparing the environment for test server_install_ubuntu
[ 0%] Creating virtual machine server
[ 0%] Taking snapshot initial for virtual machine server
[ 0%] Running test server_install_ubuntu
[ 0%] Starting virtual machine server
[ 0%] Waiting English for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Install Ubuntu Server for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Choose the language for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Select your location for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Detect keyboard layout? for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Country of origin for the keyboard for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Keyboard layout for 1m with interval 1s in virtual machine server
[ 0%] Pressing key ENTER on virtual machine server
[ 0%] Waiting Hostname: for 5m with interval 1s in virtual machine server
/home/alex/testo/hello_world.testo:61:3: Error while performing action wait Hostname: timeout 5m on virtual machine server:
-Timeout
[ 25%] Test server_install_ubuntu FAILED in 0h:5m:12s
user$

Look at that: Ubunstu installation broke up. Again. Why? Because now we have multiple NICs plugged into the virtual machine, so we get a new screen we haven't been expecting in the test script:

Primary NIC

The primary interface is listed at the top, so we just need to press Enter. Let's adjust our test script a little.

wait "Keyboard layout"; press Enter
#wait "No network interfaces detected" timeout 5m; press Enter
wait "Primary network interface"; press Enter
wait "Hostname:" timeout 5m; press Backspace*36; type "${server_hostname}"; press Enter

Run the script again, and now all the tests should pass successfully.

Unplugging the unused NIC

We've got two virtual machines, which are linked up with the LAN network. That's a progress. But before setting up IP-addresses and ping the machines, it would be good to get rid of the nat NIC.

In the preparatory tests, when we're doing the most basic setups with the virtual machines, the Internet access is, without any doubt, very important: with the Internet access you can install any missing (for the testing purposes) packages. But later the Internet access becomes just redundant and can potentially mess up our tests (of course, this depends heavily on your test cases, sometimes you need the Internet access all the time, and sometimes you don't need it at all). So let's assume that we want to get rid of the Internet access, and the question is how to do that.

In Testo-lang you have two options with NICs:

  1. Plug/unplug the "virtual link" from the NIC (plug/unplug link).
  2. Plug/unplug the NIC altogether (plug/unplug nic).

You can plug/unplug links at any time (doesn't matter whether the machine is powered on or stopped), but plugging/unplugging NICs is available only when the virtual machine is powered off.

Let's take a look at the server machine example. We declare a new test server_unplug_nat:

test server_unplug_nat: server_install_guest_additions {
    server {
        shutdown
        unplug nic nat
        start

        wait "${server_hostname} login:" timeout 2m; type "${server_login}"; press Enter
        wait "Password:"; type "${default_password}"; press Enter
        wait "Welcome to Ubuntu"
    }
}

This test begins with stopping the virtual machine. Generally speaking, there are two ways to stop a virtual machine from the outside: the stop action (mimicking power failure) and the shutdown action (mimicking pressing the power button on the machine). The shutdown action is somewhat more preferable.

When the machine is stopped, we unplug (right from the virtual PCI-express slot) the nat NIC and power on our machine again. The test is finished with a successful system login.

user$ sudo testo run hello_world.testo --stop_on_fail --param ISO_DIR /opt/iso --test_spec server_unplug_nat
UP-TO-DATE TESTS:
server_install_ubuntu
server_install_guest_additions
TESTS TO RUN:
server_unplug_nat
[ 67%] Preparing the environment for test server_unplug_nat
[ 67%] Restoring snapshot server_install_guest_additions for virtual machine server
[ 67%] Running test server_unplug_nat
[ 67%] Shutting down virtual machine server with timeout 1m
[ 67%] Unplugging nic nat from virtual machine server
[ 67%] Starting virtual machine server
[ 67%] Waiting server login: for 2m with interval 1s in virtual machine server
[ 67%] Typing "server-login" with interval 30ms in virtual machine server
[ 67%] Pressing key ENTER on virtual machine server
[ 67%] Waiting Password: for 1m with interval 1s in virtual machine server
[ 67%] Typing "1111" with interval 30ms in virtual machine server
[ 67%] Pressing key ENTER on virtual machine server
[ 67%] Waiting Welcome to Ubuntu for 1m with interval 1s in virtual machine server
[ 67%] Taking snapshot server_unplug_nat for virtual machine server
[100%] Test server_unplug_nat PASSED in 0h:0m:28s
PROCESSED TOTAL 3 TESTS IN 0h:0m:28s
UP-TO-DATE: 2
RUN SUCCESSFULLY: 1
FAILED: 0
user$

After the test is complete, we may open the virtual machine properties (with virtual manager) and make sure that it has only one NIC.

We now duplicate this test for the client machine as well.

test client_unplug_nat: client_install_guest_additions {
    client {
        shutdown
        unplug nic nat
        start

        wait "${client_hostname} login:" timeout 2m; type "${client_login}"; press Enter
        wait "Password:"; type "${default_password}"; press Enter
        wait "Welcome to Ubuntu"
    }
}
user$ sudo testo run hello_world.testo --stop_on_fail --param ISO_DIR /opt/iso --test_spec client_unplug_nat
UP-TO-DATE TESTS:
client_install_ubuntu
client_install_guest_additions
TESTS TO RUN:
client_unplug_nat
[ 67%] Preparing the environment for test client_unplug_nat
[ 67%] Restoring snapshot client_install_guest_additions for virtual machine client
[ 67%] Running test client_unplug_nat
[ 67%] Shutting down virtual machine client with timeout 1m
[ 67%] Unplugging nic nat from virtual machine client
[ 67%] Starting virtual machine client
[ 67%] Waiting client login: for 2m with interval 1s in virtual machine client
[ 67%] Typing "client-login" with interval 30ms in virtual machine client
[ 67%] Pressing key ENTER on virtual machine client
[ 67%] Waiting Password: for 1m with interval 1s in virtual machine client
[ 67%] Typing "1111" with interval 30ms in virtual machine client
[ 67%] Pressing key ENTER on virtual machine client
[ 67%] Waiting Welcome to Ubuntu for 1m with interval 1s in virtual machine client
[ 67%] Taking snapshot client_unplug_nat for virtual machine client
[100%] Test client_unplug_nat PASSED in 0h:0m:28s
PROCESSED TOTAL 3 TESTS IN 0h:0m:28s
UP-TO-DATE: 2
RUN SUCCESSFULLY: 1
FAILED: 0
user$

So we've now got two virtual machines with no redundant NICs and linked them up with the virtual network. We have just one preparatory step left to do.

Renaming NICs inside the OS

By default, the NICs are given pretty uninformative names inside the OS (ens3, ens4 and so on). Of course it would be much more convenient if we had them named accordingly to their names in the virtual machine declaration: client_side, server side and so on. We can actually achieve that with renaming NICs inside the OS based on the MAC, which we already know.

Renaming can be done with (for example), the following bash-script (download link is available at the end of the guide).

#!/bin/bash

set -e

mac=$1

oldname=`ifconfig -a | grep ${mac,,} | awk '{print $1}'`
newname=$2

echo SUBSYSTEM==\"net\", ACTION==\"add\", ATTR{address}==\"$mac\", NAME=\"$newname\", DRIVERS==\"?*\" >> /lib/udev/rules.d/70-test-tools.rules

rm -f /etc/network/interfaces
echo source /etc/network/interfaces.d/* >> /etc/network/interfaces
echo auto lo >> /etc/network/interfaces
echo iface lo inet loopback >> /etc/network/interfaces

ip link set $oldname down
ip link set $oldname name $newname
ip link set $newname up

echo "Renaming success"

Save this script in the rename_net.sh file in the same folder where the hello_world.testo file is located.

And write a test to use this script inside the server:

test server_prepare: server_unplug_nat {
    server {
        copyto "./rename_net.sh" "/opt/rename_net.sh"
        exec bash """
            chmod +x /opt/rename_net.sh
            /opt/rename_net.sh 52:54:00:00:00:bb client_side
            ip ad
        """
    }
}
user$ sudo testo run hello_world.testo --stop_on_fail --param ISO_DIR /opt/iso --test_spec server_prepare
UP-TO-DATE TESTS:
server_install_ubuntu
server_install_guest_additions
server_unplug_nat
TESTS TO RUN:
server_prepare
[ 75%] Preparing the environment for test server_prepare
[ 75%] Restoring snapshot server_unplug_nat for virtual machine server
[ 75%] Running test server_prepare
[ 75%] Copying ./rename_net.sh to virtual machine server to destination /opt/rename_net.sh with timeout 10m
[ 75%] Executing bash command in virtual machine server with timeout 10m
+ chmod +x /opt/rename_net.sh
+ /opt/rename_net.sh 52:54:00:00:00:bb client_side
Renaming success
+ ip ad
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: client_side: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:00:00:bb brd ff:ff:ff:ff:ff:ff
inet6 fe80::5054:ff:fe00:bb/64 scope link tentative
valid_lft forever preferred_lft forever
[ 75%] Taking snapshot server_prepare for virtual machine server
[100%] Test server_prepare PASSED in 0h:0m:2s
PROCESSED TOTAL 4 TESTS IN 0h:0m:2s
UP-TO-DATE: 3
RUN SUCCESSFULLY: 1
FAILED: 0
user$

In the ip command output we can see that the remaining NIC is named clear and neat: client_side.

Now we need to setup the IP-address for the NIC:

test server_prepare: server_unplug_nat {
    server {
        copyto "./rename_net.sh" "/opt/rename_net.sh"
        exec bash """
            chmod +x /opt/rename_net.sh
            /opt/rename_net.sh 52:54:00:00:00:bb client_side
            ip a a 192.168.1.1/24 dev client_side
            ip l s client_side up
            ip ad
        """
    }
}

And repeat all these steps with the client virtual machine.

user$ sudo testo run hello_world.testo --stop_on_fail --param ISO_DIR /opt/iso
Because of the cache loss, Testo is scheduled to run the following tests:
- server_prepare
Do you confirm running them? [y/N]: y
UP-TO-DATE TESTS:
server_install_ubuntu
server_install_guest_additions
server_unplug_nat
client_install_ubuntu
client_install_guest_additions
client_unplug_nat
TESTS TO RUN:
server_prepare
client_prepare
[ 75%] Preparing the environment for test server_prepare
[ 75%] Restoring snapshot server_unplug_nat for virtual machine server
[ 75%] Running test server_prepare
[ 75%] Copying ./rename_net.sh to virtual machine server to destination /opt/rename_net.sh with timeout 10m
[ 75%] Executing bash command in virtual machine server with timeout 10m
+ chmod +x /opt/rename_net.sh
+ /opt/rename_net.sh 52:54:00:00:00:bb client_side
Renaming success
+ ip a a 192.168.1.1/24 dev client_side
+ ip l s client_side up
+ ip ad
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: client_side: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:00:00:bb brd ff:ff:ff:ff:ff:ff
inet 192.168.1.1/24 scope global client_side
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe00:bb/64 scope link tentative
valid_lft forever preferred_lft forever
[ 75%] Taking snapshot server_prepare for virtual machine server
[ 88%] Test server_prepare PASSED in 0h:0m:4s
[ 88%] Preparing the environment for test client_prepare
[ 88%] Restoring snapshot client_unplug_nat for virtual machine client
[ 88%] Running test client_prepare
[ 88%] Copying ./rename_net.sh to virtual machine client to destination /opt/rename_net.sh with timeout 10m
[ 88%] Executing bash command in virtual machine client with timeout 10m
+ chmod +x /opt/rename_net.sh
+ /opt/rename_net.sh 52:54:00:00:00:aa server_side
Renaming success
+ ip a a 192.168.1.2/24 dev server_side
+ ip l s server_side up
+ ip ad
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: server_side: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:00:00:aa brd ff:ff:ff:ff:ff:ff
inet 192.168.1.2/24 scope global server_side
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe00:aa/64 scope link tentative
valid_lft forever preferred_lft forever
[ 88%] Taking snapshot client_prepare for virtual machine client
[100%] Test client_prepare PASSED in 0h:0m:4s
PROCESSED TOTAL 8 TESTS IN 0h:0m:8s
UP-TO-DATE: 6
RUN SUCCESSFULLY: 2
FAILED: 0
user$

Pinging!

Finally, all things are set up and we can check that client and server can ping each other.

Create one last test test_ping which, unlike the previous tests, has two parent-tests: client_prepare and server_prepare. We need both these tests to complete successfully to begin the ping testing.

test test_ping: client_prepare, server_prepare {
    client exec bash "ping 192.168.1.2 -c5"
    server exec bash "ping 192.168.1.1 -c5"
}

Final script run

user$ sudo testo run hello_world.testo --stop_on_fail --param ISO_DIR /opt/iso --test_spec test_ping
UP-TO-DATE TESTS:
client_install_ubuntu
client_install_guest_additions
client_unplug_nat
client_prepare
server_install_ubuntu
server_install_guest_additions
server_unplug_nat
server_prepare
TESTS TO RUN:
test_ping
[ 89%] Preparing the environment for test test_ping
[ 89%] Restoring snapshot client_prepare for virtual machine client
[ 89%] Restoring snapshot server_prepare for virtual machine server
[ 89%] Running test test_ping
[ 89%] Executing bash command in virtual machine client with timeout 10m
+ ping 192.168.1.2 -c5
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.056 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.036 ms
64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=0.046 ms
64 bytes from 192.168.1.2: icmp_seq=4 ttl=64 time=0.046 ms
64 bytes from 192.168.1.2: icmp_seq=5 ttl=64 time=0.043 ms

--- 192.168.1.2 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 3998ms
rtt min/avg/max/mdev = 0.036/0.045/0.056/0.008 ms
[ 89%] Executing bash command in virtual machine server with timeout 10m
+ ping 192.168.1.1 -c5
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.057 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.038 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.042 ms
64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=0.043 ms
64 bytes from 192.168.1.1: icmp_seq=5 ttl=64 time=0.042 ms

--- 192.168.1.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 3998ms
rtt min/avg/max/mdev = 0.038/0.044/0.057/0.008 ms
[ 89%] Taking snapshot test_ping for virtual machine client
[ 89%] Taking snapshot test_ping for virtual machine server
[100%] Test test_ping PASSED in 0h:0m:16s
PROCESSED TOTAL 9 TESTS IN 0h:0m:16s
UP-TO-DATE: 8
RUN SUCCESSFULLY: 1
FAILED: 0
user$

We can see that the ping command runs great, which means that we managed to setup a test bench with two linked up virtual machines!

Conclusions

Virtual networks can be used not only to gain the Internet access, but to link up virtual machines with each other as well.

Testo Framework allows you to develop preparatory tests with the Internet access and then unplug the NIC leading to the Internet if the Internet is not needed anymore. This way you can reduce the redundant Internet connections, that can possibly mess up the test cases.

You can simplify the NICs distibguishing inside the test scripts by assigning fixed MAC-addresses to the NICs and then renaming them inside the OS to your linking.

Tests hierarchy looks like this at the moment:

You can find the complete test scripts and NIC-renaming bash script here.