tstOVF.cpp revision 508452243fd3328f7b9e0405d39fb9dc004e31b8
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * tstOVF - testcases for OVF import and export
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Copyright (C) 2010 Oracle Corporation
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * available from http://www.virtualbox.org. This file is free software;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * General Public License (GPL) as published by the Free Software
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncusing namespace com;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync///////////////////////////////////////////////////////////////////////////////
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Quick hack exception structure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync const char *pcsz,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync if (!info.isFullAvailable() && !info.isBasicAvailable())
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync * Imports the given OVF file, with all bells and whistles.
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync * Throws MyError on errors.
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync * @param pcszPrefix Descriptive short prefix string for console output.
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync * @param pVirtualBox VirtualBox instance.
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync * @param pcszOVF0 File to import.
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync * @param llMachinesCreated out: UUIDs of machines that were created so that caller can clean up.
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync const char *pcszOVF0,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync RTPrintf("%s: reading appliance \"%s\"...\n", pcszPrefix, szAbsOVF);
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync HRESULT rc = pVirtualBox->CreateAppliance(pAppl.asOutParam());
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync if (FAILED(rc)) throw MyError(rc, "failed to create appliance\n");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rc = pAppl->Read(Bstr(szAbsOVF).raw(), pProgress.asOutParam());
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (FAILED(rc)) throw MyError(rc, "Appliance::Read() failed\n");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (FAILED(rc)) throw MyError(rc, "Progress::WaitForCompletion() failed\n");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (FAILED(rc2)) throw MyError(rc2, "Appliance::Read() failed\n", pProgress);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTPrintf("%s: interpreting appliance \"%s\"...\n", pcszPrefix, szAbsOVF);
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync if (FAILED(rc)) throw MyError(rc, "Appliance::Interpret() failed\n");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync com::SafeIfaceArray<IVirtualSystemDescription> aDescriptions;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rc = pAppl->COMGETTER(VirtualSystemDescriptions)(ComSafeArrayAsOutParam(aDescriptions));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ComPtr<IVirtualSystemDescription> pVSys = aDescriptions[u];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync com::SafeArray<VirtualSystemDescriptionType_T> aTypes;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rc = pVSys->GetDescription(ComSafeArrayAsOutParam(aTypes),
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (FAILED(rc)) throw MyError(rc, "VirtualSystemDescription::GetDescription() failed\n");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync const char *pcszType;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case VirtualSystemDescriptionType_HardDiskControllerIDE:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case VirtualSystemDescriptionType_HardDiskControllerSATA:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case VirtualSystemDescriptionType_HardDiskControllerSAS:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case VirtualSystemDescriptionType_HardDiskControllerSCSI:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync throw MyError(E_UNEXPECTED, "Invalid VirtualSystemDescriptionType\n");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTPrintf(" vsys %2u item %2u: type %2d (%s), ovf: \"%ls\", vbox: \"%ls\", extra: \"%ls\"\n",
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTPrintf("%s: importing %d machine(s)...\n", pcszPrefix, aDescriptions.size());
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rc = pAppl->ImportMachines(pProgress.asOutParam());
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (FAILED(rc)) throw MyError(rc, "Appliance::ImportMachines() failed\n");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (FAILED(rc)) throw MyError(rc, "Progress::WaitForCompletion() failed\n");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (FAILED(rc2)) throw MyError(rc2, "Appliance::ImportMachines() failed\n", pProgress);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rc = pAppl->COMGETTER(Machines)(ComSafeArrayAsOutParam(aMachineUUIDs));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (FAILED(rc)) throw MyError(rc, "Appliance::GetMachines() failed\n");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTPrintf("%s: created machine %u: %ls\n", pcszPrefix, u, aMachineUUIDs[u]);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync llMachinesCreated.push_back(Guid(Bstr(aMachineUUIDs[u])));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Copies ovf-testcases/ovf-dummy.vmdk to the given target and appends that
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * target as a string to the given list so that the caller can delete it
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * again later.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param llFiles2Delete List of strings to append the target file path to.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pcszDest Target for dummy VMDK.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync const char *pcszDest)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTPrintf("%s: copying ovf-dummy.vmdk to \"%s\"...\n", pcszPrefix, pcszDest);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int vrc = RTFileCopy("ovf-testcases/ovf-dummy.vmdk", pcszDest);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_FAILURE(vrc)) throw MyError(0, Utf8StrFmt("Cannot copy ovf-dummy.vmdk to %s: %Rra\n", pcszDest, vrc).c_str());
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param argc
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param argv[]
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (FAILED(rc)) throw MyError(rc, "failed to initialize COM!\n");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rc = pVirtualBox.createLocalObject(CLSID_VirtualBox);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (FAILED(rc)) throw MyError(rc, "failed to create the VirtualBox object!\n");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (FAILED(rc)) throw MyError(rc, "failed to create a session object!\n");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // create the event queue
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // (here it is necessary only to process remaining XPCOM/IPC events after the session is closed)
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // for each testcase, we will copy the dummy VMDK image to the subdirectory with the OVF testcase
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // so that the import will find the disks it expects; this is just for testing the import since
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // the imported machines will obviously not be usable.
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // llFiles2Delete receives the paths of all the files that we need to clean up later.
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // testcase 1: import ovf-joomla-0.9/joomla-1.1.4-ovf.ovf
09f4b412099acda62997fd82c8608075c453b3ebvboxsync copyDummyDiskImage("joomla-0.9", llFiles2Delete, "ovf-testcases/ovf-joomla-0.9/joomla-1.1.4-ovf-0.vmdk");
09f4b412099acda62997fd82c8608075c453b3ebvboxsync copyDummyDiskImage("joomla-0.9", llFiles2Delete, "ovf-testcases/ovf-joomla-0.9/joomla-1.1.4-ovf-1.vmdk");
09f4b412099acda62997fd82c8608075c453b3ebvboxsync importOVF("joomla-0.9", pVirtualBox, "ovf-testcases/ovf-joomla-0.9/joomla-1.1.4-ovf.ovf", llMachinesCreated);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // testcase 2: import ovf-winxp-vbox-sharedfolders/winxp.ovf
09f4b412099acda62997fd82c8608075c453b3ebvboxsync copyDummyDiskImage("winxp-vbox-sharedfolders", llFiles2Delete, "ovf-testcases/ovf-winxp-vbox-sharedfolders/Windows 5.1 XP 1 merged.vmdk");
09f4b412099acda62997fd82c8608075c453b3ebvboxsync copyDummyDiskImage("winxp-vbox-sharedfolders", llFiles2Delete, "ovf-testcases/ovf-winxp-vbox-sharedfolders/smallvdi.vmdk");
09f4b412099acda62997fd82c8608075c453b3ebvboxsync importOVF("winxp-vbox-sharedfolders", pVirtualBox, "ovf-testcases/ovf-winxp-vbox-sharedfolders/winxp.ovf", llMachinesCreated);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // testcase 3: import ovf-winxp-vbox-sharedfolders/winxp.ovf
09f4b412099acda62997fd82c8608075c453b3ebvboxsync importOVF("winhost-audio-nodisks", pVirtualBox, "ovf-testcases/ovf-winhost-audio-nodisks/WinXP.ovf", llMachinesCreated);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync RTPrintf("Machine imports done, no errors. Cleaning up...\n");
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // clean up the machines created
09f4b412099acda62997fd82c8608075c453b3ebvboxsync for (std::list<Guid>::const_iterator it = llMachinesCreated.begin();
09f4b412099acda62997fd82c8608075c453b3ebvboxsync rc = pVirtualBox->FindMachine(bstrUUID.raw(), pMachine.asOutParam());
09f4b412099acda62997fd82c8608075c453b3ebvboxsync if (FAILED(rc)) throw MyError(rc, "VirtualBox::FindMachine() failed\n");
09f4b412099acda62997fd82c8608075c453b3ebvboxsync RTPrintf(" Deleting machine %ls...\n", bstrUUID.raw());
09f4b412099acda62997fd82c8608075c453b3ebvboxsync rc = pMachine->Unregister(CleanupMode_DetachAllReturnHardDisksOnly,
09f4b412099acda62997fd82c8608075c453b3ebvboxsync if (FAILED(rc)) throw MyError(rc, "Machine::Unregister() failed\n");
09f4b412099acda62997fd82c8608075c453b3ebvboxsync rc = pMachine->Delete(ComSafeArrayAsInParam(sfaMedia), pProgress.asOutParam());
09f4b412099acda62997fd82c8608075c453b3ebvboxsync if (FAILED(rc)) throw MyError(rc, "Machine::DeleteSettings() failed\n");
09f4b412099acda62997fd82c8608075c453b3ebvboxsync if (FAILED(rc)) throw MyError(rc, "Progress::WaitForCompletion() failed\n");
09f4b412099acda62997fd82c8608075c453b3ebvboxsync // clean up the VMDK copies that we made in copyDummyDiskImage()
09f4b412099acda62997fd82c8608075c453b3ebvboxsync for (std::list<Utf8Str>::const_iterator it = llFiles2Delete.begin();
09f4b412099acda62997fd82c8608075c453b3ebvboxsync RTPrintf("Deleting file %s...\n", strFile.c_str());