This article is an attempt to provide an understanding of how automated testing using virtual machines can be set up, and the benefits of using this as a QA practice. Test engineers often struggle while trying to set up a quick test environment, and perform operations such as starting specific services on a virtual machine. Let’s go step by step to see how this can be done.

Let’s first understand what a test environment/test bed setup is, and why it is so important. In simple words, it includes the location for the application software, supporting data to conduct tests, and the tools required to support testing.

As testers, we perform testing on different operating systems, browsers and hardware to certify a software build. Every time there is a new build, the same set of tests are performed in a specific test environment. If we miss anything during testing, it may create problems at a later stage and reduce confidence in releasing the build. For example – a test plan requires testing an application or software on specific hardware. While preparing the test bed, if the tester misses this setting and files a defect, the developer can ignore it since that was not the expected test environment. This ends up in time wasted for both the QA tester and the developer. Automation can help a lot here, since all repetitive steps will be automated and executed every time.

A test bed or test environment is configured as per the need of the application under test. Key aspects of test setup include

  • Hardware and Operating system
  • System and applications
  • Test data
  • Database server
  • Front end running environment
  • Browsers
  • Network

Setting up a test environment is really complex, and the right process needs to be followed. Without going into detail, this broadly includes the following

  • Prepare a test environment checklist( it includes types of hardware, OS and other requirements).
  • Prepare a document that states the challenges that might be faced while setting up the environment.
  • Follow best practices.

Testing automation is simply the process of using software tools to perform testing procedures that were previously done manually. Automation may be applied to some or all of the procedures involved in performing a test. The process of adding automation to any testing environment requires a certain amount of work to be done to implement the tools chosen to perform the automated tasks. While setting up a test environment, we frequently use virtual machines to speed up the test environment setup without any error. We install certain softwares, set browsers, keep the test data on the virtual environment and take snapshots. While running the same test suite again, we simply switch our virtual machine to the starting point, saving a lot of time here. Let’s understand how to easily setup a test environment using the VMware virtual environment. I assume you are familiar with the ESXi server, vSphere client, Snapshot etc.

Approach 1: Using Jenkins CI.

Step 1: Install vSphere Cloud Plugin from the Jenkins plugin installation page.

Click on Manage Jenkins → Manage Plugins

Image_1

Step 2: Go to the ‘Available’ Tab, select “vSphere Plugin” and install it.

Step 3: Next, configure Jenkins to address what vSphere server will be used. Add a new “Cloud” in the Jenkins “Configure System” menu. Click on Manage Jenkins → Configure System. Enter vSphere Host IP (ESXi server IP), Credentials and Name. Test the connectivity and save it. You can add multiple ESXi servers as well.

Image_2

Step 4: Now everything is set and you can control your virtual machine available on this ESXi server. Create a job and add build step by ‘vSphere build step‘.

Image_3

This will add the following section in the job. Select appropriate action and enter data in the remaining fields. Enter the virtual machine name and snapshot name in the fields VM and Snapshot Name respectively.

Image_4

Approach 2: Vmware provides Python API for interacting with vSphere Web Services. Using these APIs you can clone virtual machines, power off/power on, create a snapshot, or perform all operations asynchronously to speed up the tasks on multiple virtual machines.

PySphere provides easy interfaces to: ( taken from Here. )

  • Connect to VMWare’s ESX, ESXi, Virtual Center, Virtual Server hosts
  • Query hosts, datacenters, resource pools, virtual machines
  • VMs: Power on, power off, reset, revert to snapshot, get properties, update vmware tools, clone, migrate.
  • vSphere 5.0 Guest Operations: create/delete/move files and directories. upload/download files from the guest system. List/start/stop processes in the guest system.
  • Create and delete snapshots
  • Get hosts statistics and monitor performance

Installation of python module.

pip install -U PySphere

You can also find the source package and windows installer in the downloads section. To install it from the source package:

  • Unzip the package
  • run: python setup.py install

Now let’s check if pysphere works to expectations or not. Open CMD on Windows or Console on Unix or Mac OS.

Run Python and import Pysphere module, as follows:

>>> from pysphere import VIServer
>>> server = VIServer()
>>> server.connect("192.168.1.5", "testuser", "testpassword")
>>> vm = server.get_vm_by_path("[datastore] path/to/file.vmx")
>>> vm.power_on()
>>> print vm.get_status()

POWERED ON
If you see this  error “ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)” while executing the above sample code, please install python ssl module and import it.  More information on this error, and how to resolve it is provided here. Your final code looks like…

from pysphere import VIServer
import ssl
server = VIServer() ## Create vSphere instance
default_context = ssl._create_default_https_context

try:

#https://www.python.org/dev/peps/pep-0476/
ssl._create_default_https_context = ssl._create_unverified_context
server.connect("192.168.1.6", "root", "YourPassword")

finally:

print "vserver: AFTER CONNECTION - [{}] [{}]".format(server.get_server_type(), server.get_api_version())
if server.is_connected():
  print "Connected to the server 192.168.1.6"
else:
  print "Opps! Not Connected"

Ok, you just wrote your  first python program that connects to the Vmware server (ESXi) and prints some information about the server. The  code is self explanatory so without getting into detail, let’s understand a few more APIs.

There are two main methods you can use to get a VM instance:

get_vm_by_path: Retrieve a virtual machine by its virtual machine configuration file path.

get_vm_by_name: Retrieve a virtual machine by its assigned name. It’s recommended that you use the first method. This method will return the first VM to be found in case you have two VMs with the same name.

from pysphere import VIServer
import ssl
server = VIServer() ## Create vSphere instance
server.connect("192.168.1.6", "root", "YourPassword")
vm1 = server.get_vm_by_path("[DataStore1] path1/to/Ubuntu-14.vmx")
vm2 = server.get_vm_by_name("Ubuntu 14")

These APIs can take additional data center parameters like the resource pool as well to refine the search.

 vm1 = server.get_vm_by_path("[DataStore1] path1/to/Ubuntu-14.vmx", "DEV")
 vm2 = server.get_vm_by_name("Ubuntu 14", "QA”)
 #Getting VM properties Virtual Machine Status.
 print vm1.get_status()

In real time situations, when we deploy virtual machines and check their status, we find that they are usually in a  “Powered OFF” state. When we switch to “Powered ON”on and check the status, they could be in either Powering  ON or Powered ON state. Using pysphere module apis, we can check the intermediate status of the action.

POWERED OFF →      POWERING ON → POWERED ON.

get_status()      or →    is_powering_on() → get_status() or

is_powered_off()                                is_powered_on()

 from pysphere import VIServer
 server = VIServer() ## Create vSphere instance
 server.connect("192.168.1.6", "root", "YourPassword")
 vm1 = server.get_vm_by_name("Ubuntu 14")
 if vm1.is_powered_on() :
      print “VM machine Ubuntu 14 is up and running.”

You have now Powered ON your virtual machine and want to know the IP of that machine. Also, you want to take a snapshot of the current stage of your virtual machine for future use.

 from pysphere import VIServer
 server = VIServer() ## Create vSphere instance
 server.connect("192.168.1.6", "root", "YourPassword")
 vm1 = server.get_vm_by_name("Ubuntu 14")
 if vm1.is_powered_on() :
     print “VM machine Ubuntu 14 is up and running.”
     #Get IP Address
     print vm1.get_property('ip_address', from_cache=False)
     # Take a snapshot of a virtual machine VM1.
     vm1.create_snapshot(“Name_of_Snapshot”)

Once you have the snapshot, you can control it by performing different operations. Again, if you need the name of your current snapshot, if any, use

vm1.get_current_snapshot_name()

This does not take any argument.You can revert to a particular snapshot, via multiple options

Revert to current snapshot.

 vm1.revert_to_snapshot()

Revert to named snapshot

 vm1.revert_to_named_snapshot(“Name_of_Snapshot”)

Revert to the snapshot of the given path and index.

 vm1.revert_to_path(“vmfolder/path/abc/vmx”)


In the same way, you can delete any snapshot using following APIs.

 delete_current_snapshot
 delete_named_snapshot
 delete_snapshot_by_path

Part 2: Guest Machine Operations
So far we have performed a few actions on the virtual machine, but what if we want to execute a command in the currently running virtual machine? In automated testing, we often need to run services after powering on the virtual machine – create the test data folder, or copy some files from the local machine to the virtual machine, or start the Apache server, or upgrade the browser version. Maybe you have a Windows bat file or unix shell script file that needs to be executed when you start the VM.
VMware provides VMware Tools, a suite of utilities that enhances the performance of the virtual machine’s guest operating system and improves management of the virtual machine. You need to install it on the virtual machine (Guest Machine) and keep it updated and running on the Guest machine. To get more information about VMware tools, click here.
To execute any command on a guest machine (Your virtual machine will need to be controlled using APIs.), you need to first login in the guest OS and Vm1.login_in_guest is the api to use here.

Please note that if  VMtools on the virtual machine is not the latest version, you will not be able to execute commands. So check the status of VMtools and upgrade if required. To upgrade vmware tools, you can run upgrade_tools api.

 vm1.get_tools_status()  returns the status of the vmtools.  Status could be any one of the following

Not Installed: VMware tools has not installed or run in the VM.
Not Running:  VMware tools is not running.
Running:          VMware tools is running and the version is current.
Running Old:   VMware tools is running but not latest one.
Unknown:  Could not obtain the status of the VMware tools.
Let’s assume that our virtual machine is running current VMware tools so we can control it. We need to login to the VM. If you don’t get any exception after executing the following API, you are logged in to the guest machine and you can perform files and directories operations on the guest system.

 vm1.login_in_guest(“User_name” “user_password)

# Create a directory in the guest OS. You need to pass complete path to be created. If parent directories do not exist, they will be created by default. This API has a second parameter create_parents=True. By default it is set to True. Set it to False to create only the last directory in the existing folder path.

vm1.make_directory(“full/path/to/be/created”)
# Get a list of directories, using
 vm1.get_directory()            
# Move or rename a directory In the guest using
 vm1.move_directory(src_path, dst_path)
# Delete Directory in the guest OS
 vm1.delete_directory(“directory/to/be/deleted”)
# List the files available in the specific path in the guest machine. It will return filtered output if Match patterns are specified.
 Vm1.list_files(path, match_pattern=None)
# Send file to guest machine or get/retrieve file from guest machine.
# Send  directory from local to the guest machine recursively.
 vm1.send_directory(self, local_path, guest_path, overwrite=False)
# Transfer a file to the guest machine from local machine.
 vm1.send_file(local_path, guest_path, overwrite=False)
# Transfer a file from the guest machine to a local machine.
 vm1.get_file(guest_path, local_path, overwrite=False)
# Move and delete file operations can be done through following APIs,
 vm1.move_file(src_path, dst_path, overwrite=False)
 vm1.delete_file(path)

Part 3: Handling the process on the guest machine and a list of the other APIs that can be used at  guest level or server level.
Sometimes you need to manage processes on the guest machine. You may need to start a process, or stop or kill a process. Some time process performance has to be checked as well.  VMware provides APIs those control processes on guest machines.
APIs include
# List the processes running in the guest operating system

 vm1.list_processes()

# Starts a program in the guest operating system. Returns the process PID.

 vm1.start_process(program_path, args=None, env=None, cwd=None, sync_run=False, timeout=0)

program_path = The absolute path to the program to start.
cwd=The absolute path of the working directory for the program to be run.
# Terminates a process in the guest OS

 vm1.terminate_process()

# Reads the environment variables from the guest OS (system user). Returns a dictionary where keys are the var names and the dict value is the var value

 vm1.get_environment_variables()

There are few more APIs using which you can clone a virtual machine, reserve memory, set CPU reservation, set resource pool etc. Please visit this url to get more information.

To get all powered on VMs from the ‘Windows XP’ resource pool:

 vmlist = server.get_registered_vms(resource_pool='Windows XP', status='poweredOn')

Finally do not forget to disconnect the connection. To disconnect from the server, use

server.disconnect()

Before we conclude, there is one last thing to bear in mind.  Often times in automation, we use many virtual machines and we need to power on/power off/switch to snapshot simultaneously. In this case we should execute this API in such a way that we regain control immediately, and can run the next command/api. By default,all APIs get  executed synchronously, which  means the method won’t return until the requested operation has completed. If you want to execute those operation asynchronously, you must provide the keyword argument sync_run=False

Hope you find this information useful in your automation exercise.

This article was authored by Bharat Patel, who is a Principal Engineer - QA, Zymr.

0 comments

Leave a Reply

© 2019, Zymr, Inc. All Rights Reserved.| LEGAL DISCLAIMER | PRIVACY POLICY | COOKIE POLICY