Expanding a VM’s Hard Drive

Today, I needed to expand the hard drive in a VMware Workstation 6.5 image. It’s a simple process, but can be non-trivial if you don’t know where to start. I’ve posted the steps below, (much more for my reference than anyone else’s 😉 )

  1. Open a command prompt, and CD to the directory which contains the VMDK file you wish to expand.
  2. Use the command “C:\Program Files\VMware\VMware Workstation\vmware-vdiskmanager.exe –x 6GB ‘Windows XP Professional’”, where ‘Windows XP Professional’ is the name of the Virtual Machine Disk File. This will increase the disk allocation to 6GB, (this may take a while).
  3. Now to join the unallocated space to the primary partition – Ensure your image is powered off, and is set to mount the gparted ISO, (can be downloaded here). This can be changed in the image options under Settings -> CD/DVD. Select the ‘Use ISO image:’ option and point it to the gparted ISO.
  4. Next Power on the Virtual Machine, press ESC at the BIOS screen to get to the Boot Menu. Select CD-ROM as the Boot device.
  5. Gnome Partition Editor will load, press Enter at the boot screen. Select all options as they are asked as default, (ensure you select English as your language.)
  6. To complete the join of the unallocated space to your partition, complete the following steps:

• Once the partition editor loads, click on /dev/sda1 in the partition list.
• Click the Resize/Move button.
• Click and drag the arrow to extend the size of the partition, make sure you do a resize (double arrow) and not a move (four way arrow) so you should have 0mb free space preceding and following, and then click the Resize/Move button.
• Next click the Apply button and then the operation will start, you can expand Details to see the progress, once completed click the Close button.
• Click the power button in the top left corner, then select reboot.
• Edit the VM and remove the ISO from the CD/ROM device.
• When the OS restarts it will do a Check Disk, let this complete, Windows will prompt for a reboot after you login.
• Reboot and load Disk Management (diskpart.exe -> Show volume) and your Primary Partition will be the new size without any unallocated space.

See, it’s as easy as that 🙂 …

Programmatically verify resources in a DLL

I had a requirement recently to be able to programmatically check certain resources were contained in a set of (native) DLL resource files. The idea behind this was to add some post-build automated engineering checks to our existing automated test suite, e.g. ensuring resources for all the required languages have been injected correctly.

I wanted to write a simple C# application to perform these checks. I came accross this handy library which contained functions for almost all the functionality I required:

ResourcesLib

Using this, we can perform functions such as importing resources, loading strings, and even injecting new resources.

For example, here’s how you could retrieve all languages contained in a resource DLL:

string file = "resource.dll";
RawResourceFile resFile = new RawResourceFile();
resFile.Load(file);

for (int i = 0; i < resFile.Languages.Count; i++) { Console.WriteLine("Language: " + resFile.Languages[i]); }

Download the library and take a look, it can save you lots of time if you need to perform any checks/actions on DLL file.

Developing Language Independent test automation

At my day job, we’re currently developing an automation suite to perform Build Verification Testing (BVT) and some basic functional testing on new builds coming into QA. This is a challenge in itself, but becomes even more difficult when you consider we currently release products across 28 distinct locales, including right-to-left languages like Arabic and Hebrew.

The drawback of this, is that we need to think of the bigger picture when writing an automation script/program. A program we develop to perform some action on an English build, on an English XP, may not perform as expected on say a German build on a German language version of XP.

Here are some general guidelines I’ve learnt along the way, to keep in mind when developing automation scripts/programs that you intend to run accross multiple languages/platforms.

1. Never hard code language dependent information

I’ve seen this a lot. Such information may be the expected title of an alert, that appears when the script performs some action. Hard-coding the expected alert title in English will cause the script to be useless on any other language. All these strings should be externalised in some way, even to a simple text file.

2. Never hard code paths to Windows system folders

Hard-coding these paths, such as the paths to ‘Program Files’ or the ‘Documents and Settings’ folder will cause your automation to fail on non-English platforms. The problem with these is that they may be localized on some environments. For example, ‘Program Files’ becomes ‘Programme’ on a German environment. If you need to use these paths, always use the Windows environment variables to retrieve the value, that way you can be sure the path will be valid for that platform.

For example, retrieving the path to the ‘Program Files’ directory (in VBScript):


Set oShell = CreateObject( "WScript.Shell")
strProgramFilesDir = oShell.ExpandEnvironmentStrings("%PROGRAMFILES%")

Where an environment variable is not available, you can usually find the path in the Windows registry with some Googling. For example, the ‘All Users\Application Data’ folder can be found at the registry location below on all Windows variants:


HKLM\Software\Microsoft\Windows\Explorer\Shell Folders\Common AppData

3. Don’t assume elements will always be in the same place

In controls such as drop-down menus, the order of the items will be different on each language. Assuming the same order will cause unexpected results or cause your automated tests to fail outright. Also, in RTL languages such as Arabic, the elements themselves will be in a completely different area on the dialog.

4. Never hard-code date formats

Always use the date and time formatting functions provided by the development language you are working with. Also, a common error I’ve seen is that developers assume the date seperator used is always the same, not true! This is a ‘-‘ (hyphen) on an English platform, whereas a ‘.’ (period) on a German environment.

For example,


31.12.2009 - Germany
31/12/2009 - Belgium
31-12-2009 - Ireland

5. Never use ‘record and playback’ automation tools

These are pretty useless in an environment where you are attempting to develop automation to run across multiple languages, with the obvious example being attempting to run a script on an Arabic build which you previously recorded on an English build, where the dialogs are mirrored and the elements are in completely different areas of the screen.

6. Create automation which is resistant to changes in the UI

A couple of string changes in the UI should not cause your automation to fail. Use Object ID’s where possible, as these will rarely change, and it’s easy to add a fix if they do.

Just adhering to the above simple guidelines should solve many of the common issues encountered when attempting to develop an automation suite to run across multiple languages.

Automating Virtual Machine operations on ESXi Server from C#

VMware provides two really useful API’s for automating virtual machine (VM) tasks on both VMware Workstation and VMware ESXi server.

  • VI Infrastructure API
  • VIX API

These are extremely easy to use from C#. In a QA environment, the automation of VM’s can be hugely benifical, wheather attempting to automate an environment for build sanity checks or functional tests.

This post will outline the basics of using the VIX API from C#, in order to perform operations on VMware ESXi server. If you don’t have access to an ESXi server, you can install it on a VM, it’s free to download from the VMware website!

For starters, you will need to install the API’s on your development machine. In order to download, you will need to create a VMware account, which you may already have if you have downloaded Workstation or ESXi server in the past. If you dont, you can create an account for free. Once logged into your account, you can download both API’s from the ‘Support & Downloads’ section.

Let me explain the differance between these two API’s. From VMware’s own documentation:

The VI API provides access to the VMware Infrastructure management components—the managed objects that can be used to manage, monitor, and control life-cycle operations of virtual machines and other VMware infrastructure components (datacenters, datastores, networks, and so on).”

VIX on the other hand, is used to automate the actual operations on VM’s, such as booting them, copying in files, getting/setting VM environment varibles and other tasks you may wish to perform. The coolest part of VIX is that a wrapper for C# exists, created by Daniel Doubrovkine over at dblock.org. This wrapper, ‘VMwareTasks’, provides a simple object-orientated approach to VIX, which will be familar to C# developers. Download the wrapper here.

Now for the basics of using the VIX API and VMwareTasks wrapper. Create a new console application project in Visual Studio. You will need to add a reference to the VMwareTasks DLL, which is located in the ‘bin’ directory when you extract the VMwareTasks download.

Look how simple it is to power on a VM!


// Declare a new virtual host
VMWareVirtualHost host = new VMWareVirtualHost();

// Connect to the ESXi server
host.ConnectToVMWareVIServer("192.168.1.39", "root", "password123");

// Power on an existing VM by name
VMWareVirtualMachine machine = host.Open("[datastore1] XPP_SP2.vmx");
machine.PowerOn();

The simple code above just connects to an ESXi server, and powers on an existing VM, but you can see how easy it is to perform operations on VM’s.

Here’s how to create and revert to a snapshot:


VMWareVirtualHost host = new VMWareVirtualHost();
host.ConnectToVMWareVIServer("192.168.1.39", "root", "password123");
VMWareVirtualMachine machine = host.Open("[datastore1] Vista_EN.vmx");
machine.PowerOn();
machine.Login("Tester", "testing");

string snapShotName = "base";
machine.Snapshots.CreateSnapshot(snapShotName, "Clean");
machine.PowerOff();

VMWareSnapshot snapshot = machine.Snapshots.GetNamedSnapshot("base");
snapshot.RevertToSnapshot();

Or to create a directory:


machine.CreateDirectoryInGuest(@"C:\TestDir");

You can see from the above examples how easy it is to perform operations on VM’s using these API’s. Install the API’s and play around with the functionality, I guarantee you’ll be impressed!

Blog goes live!

Welcome to my blog! Live as of January 31st 2010 at http://www.jimmycollins.org/blog.

I’ve just installed WordPress in order to get this blog up and running, and I have to say it was one of the most flawless processes I have ever been through. The famous WordPress ‘5 minute install’ actually took me around 3 minutes.

I had intended to develop a custom blogging application as an exercise in C# or PHP, but really didn’t have the time. Maybe I will do this in the future, but for now I’m pretty happy with the WordPress installation.

I intend the content of this blog to be mostly technical. Likely topics include C#, PHP, VBScript development, QTP automation, and Virtualization topics such as VMware ESX server management.

More soon!