You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ml...@apache.org on 2013/01/29 22:26:58 UTC

git commit: Summary: Add tests, streamline code by removing custom addUserVmToNetwork

Updated Branches:
  refs/heads/add_remove_nics 77da8856f -> aff919eab


Summary: Add tests, streamline code by removing custom addUserVmToNetwork

Submitted-by: Brian Angus <bl...@betterservers.com>
Submitted-by: Ryan Dietrich <ry...@betterservers.com>
Signed-off-by: Marcus Sorensen <ma...@betterservers.com> 1359494800 -0700


Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/aff919ea
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/aff919ea
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/aff919ea

Branch: refs/heads/add_remove_nics
Commit: aff919eab3bda9fa7a51da5a966b678dae3d3c4c
Parents: 77da885
Author: Marcus Sorensen <ma...@betterservers.com>
Authored: Tue Jan 29 14:26:40 2013 -0700
Committer: Marcus Sorensen <ma...@betterservers.com>
Committed: Tue Jan 29 14:26:40 2013 -0700

----------------------------------------------------------------------
 server/src/com/cloud/network/NetworkManager.java   |    2 +-
 .../src/com/cloud/network/NetworkManagerImpl.java  |    6 +-
 server/src/com/cloud/vm/UserVmManagerImpl.java     |   20 +-
 server/src/com/cloud/vm/VirtualMachineManager.java |   12 -
 .../com/cloud/vm/VirtualMachineManagerImpl.java    |   59 +---
 .../com/cloud/network/MockNetworkManagerImpl.java  |    2 +-
 .../cloud/vm/MockVirtualMachineManagerImpl.java    |    9 -
 .../test/com/cloud/vpc/MockNetworkManagerImpl.java |    2 +-
 test/integration/smoke/test_nic.py                 |  324 +++++++++++++++
 9 files changed, 357 insertions(+), 79 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/aff919ea/server/src/com/cloud/network/NetworkManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java
index 695a8f0..c0065dd 100755
--- a/server/src/com/cloud/network/NetworkManager.java
+++ b/server/src/com/cloud/network/NetworkManager.java
@@ -262,7 +262,7 @@ public interface NetworkManager  {
      * @throws InsufficientCapacityException
      * @throws ResourceUnavailableException
      */
-    NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context, VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare, boolean alwayscreate) throws InsufficientVirtualNetworkCapcityException,
+    NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context, VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare) throws InsufficientVirtualNetworkCapcityException,
             InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException;
 
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/aff919ea/server/src/com/cloud/network/NetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java
index d1c3181..2dd6818 100755
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@ -3355,7 +3355,7 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener {
     }
     
     @Override
-    public NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context, VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare, boolean alwayscreate)
+    public NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context, VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare)
             throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException,
             ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
                 
@@ -3366,8 +3366,8 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener {
                 
                 NicProfile nic = getNicProfileForVm(network, requested, vm);
                 
-                //1) allocate nic (if needed)
-                if (nic == null || alwayscreate) {
+                //1) allocate nic (if needed) Always allocate if it is a user vm
+                if (nic == null || (vmProfile.getType() == VirtualMachine.Type.User)) {
                     int deviceId = _nicDao.countNics(vm.getId());
                     
                     nic = allocateNic(requested, network, false, 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/aff919ea/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 692cf4a..e00da92 100644
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -944,6 +944,12 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
         // Perform permission check on VM
         _accountMgr.checkAccess(caller, null, true, vmInstance);
 
+        // Verify that zone is not Basic
+        DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterIdToDeployIn());
+        if (dc.getNetworkType() == DataCenter.NetworkType.Basic) {
+            throw new CloudRuntimeException("Zone " + vmInstance.getDataCenterIdToDeployIn() + ", has a NetworkType of Basic. Can't add a new NIC to a VM on a Basic Network");
+        }
+
         // Perform account permission check on network
         if (network.getGuestType() != Network.GuestType.Shared) {
             // Check account permissions
@@ -975,7 +981,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
         NicProfile guestNic = null;
 
         try {
-            guestNic = _itMgr.addUserVmToNetwork(vmInstance,_vmDao.findById(vmInstance.getId()), network, profile);
+            guestNic = _itMgr.addVmToNetwork(vmInstance, network, profile);
         } catch (ResourceUnavailableException e) {
             throw new CloudRuntimeException("Unable to add NIC to " + vmInstance + ": " + e);
         } catch (InsufficientCapacityException e) {
@@ -1013,6 +1019,12 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
         // Perform permission check on VM
         _accountMgr.checkAccess(caller, null, true, vmInstance);
 
+        // Verify that zone is not Basic
+        DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterIdToDeployIn());
+        if (dc.getNetworkType() == DataCenter.NetworkType.Basic) {
+            throw new CloudRuntimeException("Zone " + vmInstance.getDataCenterIdToDeployIn() + ", has a NetworkType of Basic. Can't remove a NIC from a VM on a Basic Network");
+        }
+
         //check to see if nic is attached to VM
         if (nic.getInstanceId() != vmId) {
             throw new InvalidParameterValueException(nic + " is not a nic on  " + vmInstance);
@@ -1070,6 +1082,12 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
         // Perform permission check on VM
         _accountMgr.checkAccess(caller, null, true, vmInstance);
 
+        // Verify that zone is not Basic
+        DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterIdToDeployIn());
+        if (dc.getNetworkType() == DataCenter.NetworkType.Basic) {
+            throw new CloudRuntimeException("Zone " + vmInstance.getDataCenterIdToDeployIn() + ", has a NetworkType of Basic. Can't change default NIC on a Basic Network");
+        }
+
         // no need to check permissions for network, we'll enumerate the ones they already have access to
         Network existingdefaultnet = _networkModel.getDefaultNetworkForVm(vmId);
         

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/aff919ea/server/src/com/cloud/vm/VirtualMachineManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/VirtualMachineManager.java b/server/src/com/cloud/vm/VirtualMachineManager.java
index 2d70166..53bd442 100644
--- a/server/src/com/cloud/vm/VirtualMachineManager.java
+++ b/server/src/com/cloud/vm/VirtualMachineManager.java
@@ -154,18 +154,6 @@ public interface VirtualMachineManager extends Manager {
 
     /**
      * @param vm
-     * @param network
-     * @param requested TODO
-     * @return
-     * @throws ConcurrentOperationException
-     * @throws ResourceUnavailableException
-     * @throws InsufficientCapacityException
-     */
-    NicProfile addUserVmToNetwork(VirtualMachine vm,UserVmVO vmVO, Network network, NicProfile requested) throws ConcurrentOperationException,
-                ResourceUnavailableException, InsufficientCapacityException;
-
-    /**
-     * @param vm
      * @param nic
      * @return
      * @throws ResourceUnavailableException 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/aff919ea/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
index 7ab9309..19756ad 100755
--- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -2462,7 +2462,12 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
                                                     ResourceUnavailableException, InsufficientCapacityException {
         
         s_logger.debug("Adding vm " + vm + " to network " + network + "; requested nic profile " + requested);
-        VMInstanceVO vmVO = _vmDao.findById(vm.getId());
+        VMInstanceVO vmVO;
+        if (vm.getType() == VirtualMachine.Type.User) {
+            vmVO = _userVmDao.findById(vm.getId());
+        } else {
+            vmVO = _vmDao.findById(vm.getId());
+        }
         ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(User.UID_SYSTEM), 
                 _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM));
         
@@ -2476,7 +2481,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
         //check vm state
         if (vm.getState() == State.Running) {
             //1) allocate and prepare nic
-            NicProfile nic = _networkMgr.createNicForVm(network, requested, context, vmProfile, true, false);
+            NicProfile nic = _networkMgr.createNicForVm(network, requested, context, vmProfile, true);
             
             //2) Convert vmProfile to vmTO
             HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType());
@@ -2498,55 +2503,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
             }
         } else if (vm.getState() == State.Stopped) {
             //1) allocate nic
-            return _networkMgr.createNicForVm(network, requested, context, vmProfile, false, false);
-        } else {
-            s_logger.warn("Unable to add vm " + vm + " to network  " + network);
-            throw new ResourceUnavailableException("Unable to add vm " + vm + " to network, is not in the right state",
-                    DataCenter.class, vm.getDataCenterIdToDeployIn());
-        }
-    }
-
-    @Override
-    public NicProfile addUserVmToNetwork(VirtualMachine vm, UserVmVO vmVO, Network network, NicProfile requested) throws ConcurrentOperationException,
-                                                    ResourceUnavailableException, InsufficientCapacityException {
-
-        s_logger.debug("Adding vm " + vm + " to network " + network + "; requested nic profile " + requested);
-        ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(User.UID_SYSTEM),
-                _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM));
-
-        VirtualMachineProfileImpl<UserVmVO> vmProfile = new VirtualMachineProfileImpl<UserVmVO>(vmVO, null,
-                null, null, null);
-
-        DataCenter dc = _configMgr.getZone(network.getDataCenterId());
-        Host host = _hostDao.findById(vm.getHostId()); 
-        DeployDestination dest = new DeployDestination(dc, null, null, host);
-        
-        //check vm state
-        if (vm.getState() == State.Running) {
-            //1) allocate and prepare nic
-            NicProfile nic = _networkMgr.createNicForVm(network, requested, context, vmProfile, true, true);
-            
-            //2) Convert vmProfile to vmTO
-            HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType());
-            VirtualMachineTO vmTO = hvGuru.implement(vmProfile);
-            
-            //3) Convert nicProfile to NicTO
-            NicTO nicTO = toNicTO(nic, vmProfile.getVirtualMachine().getHypervisorType());
-            
-            //4) plug the nic to the vm
-            VirtualMachineGuru<UserVmVO> vmGuru = getVmGuru(vmVO);
-            
-            s_logger.debug("Plugging nic for vm " + vm + " in network " + network);
-            if (vmGuru.plugNic(network, nicTO, vmTO, context, dest)) {
-                s_logger.debug("Nic is plugged successfully for vm " + vm + " in network " + network + ". Vm  is a part of network now");
-                return nic;
-            } else {
-                s_logger.warn("Failed to plug nic to the vm " + vm + " in network " + network);
-                return null;
-            }
-        } else if (vm.getState() == State.Stopped) {
-            //1) allocate nic
-            return _networkMgr.createNicForVm(network, requested, context, vmProfile, false, true);
+            return _networkMgr.createNicForVm(network, requested, context, vmProfile, false);
         } else {
             s_logger.warn("Unable to add vm " + vm + " to network  " + network);
             throw new ResourceUnavailableException("Unable to add vm " + vm + " to network, is not in the right state",

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/aff919ea/server/test/com/cloud/network/MockNetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java
index 850d92a..c9446bb 100755
--- a/server/test/com/cloud/network/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java
@@ -733,7 +733,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS
      */
     @Override
     public NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context,
-            VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare, boolean alwayscreate)
+            VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare)
             throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException,
             ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
         // TODO Auto-generated method stub

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/aff919ea/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java b/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java
index 403055b..862bb25 100755
--- a/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java
+++ b/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java
@@ -271,15 +271,6 @@ public class MockVirtualMachineManagerImpl implements VirtualMachineManager {
     }
 
     /* (non-Javadoc)
-     * @see com.cloud.vm.VirtualMachineManager#addVmToNetwork(com.cloud.vm.VirtualMachine, com.cloud.network.Network, com.cloud.vm.NicProfile)
-     */
-    @Override
-    public NicProfile addUserVmToNetwork(VirtualMachine vm, UserVmVO vmVO,  Network network, NicProfile requested) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /* (non-Javadoc)
      * @see com.cloud.vm.VirtualMachineManager#removeVmFromNetwork(com.cloud.vm.VirtualMachine, com.cloud.network.Network, java.net.URI)
      */
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/aff919ea/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
index c55b4c0..a5a9938 100644
--- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
@@ -1127,7 +1127,7 @@ public class MockNetworkManagerImpl implements NetworkManager, NetworkService, M
      */
     @Override
     public NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context,
-            VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare, boolean alwayscreate)
+            VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare)
             throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException,
             ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
         // TODO Auto-generated method stub

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/aff919ea/test/integration/smoke/test_nic.py
----------------------------------------------------------------------
diff --git a/test/integration/smoke/test_nic.py b/test/integration/smoke/test_nic.py
new file mode 100644
index 0000000..4b31b34
--- /dev/null
+++ b/test/integration/smoke/test_nic.py
@@ -0,0 +1,324 @@
+""" NIC tests for VM """
+import marvin
+from marvin.cloudstackTestCase import *
+from marvin.cloudstackAPI import *
+from marvin.remoteSSHClient import remoteSSHClient
+from marvin.integration.lib.utils import *
+from marvin.integration.lib.base import *
+from marvin.integration.lib.common import *
+from nose.plugins.attrib import attr
+
+import signal
+import sys
+import time
+
+class Services:
+    def __init__(self):
+        self.services = {
+            "disk_offering":{
+                "displaytext": "Small",
+                "name": "Small",
+                "disksize": 1
+            },
+            "account": {
+                "email": "test@test.com",
+                "firstname": "Test",
+                "lastname": "User",
+                "username": "test",
+                # Random characters are appended in create account to
+                # ensure unique username generated each time
+                "password": "password",
+            },
+            # Create a small virtual machine instance with disk offering
+            "small": {
+                "displayname": "testserver",
+                "username": "root", # VM creds for SSH
+                "password": "password",
+                "ssh_port": 22,
+                "hypervisor": 'XenServer',
+                "privateport": 22,
+                "publicport": 22,
+                "protocol": 'TCP',
+            },
+            "service_offerings": {
+                "tiny": {
+                    "name": "Tiny Instance",
+                    "displaytext": "Tiny Instance",
+                    "cpunumber": 1,
+                    "cpuspeed": 100, # in MHz
+                    "memory": 128, # In MBs
+                },
+            },
+            "network_offering": {
+                "name": 'Test Network offering',
+                "displaytext": 'Test Network offering',
+                "guestiptype": 'Isolated',
+                "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding',
+                "traffictype": 'GUEST',
+                "availability": 'Optional',
+                "serviceProviderList" : {
+                    "Dhcp": 'VirtualRouter',
+                    "Dns": 'VirtualRouter',
+                    "SourceNat": 'VirtualRouter',
+                    "PortForwarding": 'VirtualRouter',
+                },
+            },
+            "network": {
+                "name": "Test Network",
+                "displaytext": "Test Network",
+                "acltype": "Account",
+            },
+            # ISO settings for Attach/Detach ISO tests
+            "iso": {
+                "displaytext": "Test ISO",
+                "name": "testISO",
+                "url": "http://iso.linuxquestions.org/download/504/1819/http/gd4.tuwien.ac.at/dsl-4.4.10.iso",
+                 # Source URL where ISO is located
+                "ostype": 'CentOS 5.3 (64-bit)',
+                "mode": 'HTTP_DOWNLOAD', # Downloading existing ISO 
+            },
+            "template": {
+                "displaytext": "Cent OS Template",
+                "name": "Cent OS Template",
+                "passwordenabled": True,
+            },
+            "diskdevice": '/dev/xvdd',
+            # Disk device where ISO is attached to instance
+            "mount_dir": "/mnt/tmp",
+            "sleep": 60,
+            "timeout": 10,
+            #Migrate VM to hostid
+            "ostype": 'CentOS 5.3 (64-bit)',
+            # CentOS 5.3 (64-bit)
+        }
+
+class TestDeployVM(cloudstackTestCase):
+
+    def setUp(self):
+        self.cleanup = []
+        self.cleaning_up = 0
+
+        def signal_handler(signal, frame):
+            self.tearDown()
+            sys.exit(0)
+
+        # assign the signal handler immediately
+        signal.signal(signal.SIGINT, signal_handler)
+
+        try:
+            self.apiclient = self.testClient.getApiClient()
+            self.dbclient  = self.testClient.getDbConnection()
+            self.services  = Services().services
+
+            # Get Zone, Domain and templates
+            domain = get_domain(self.apiclient, self.services)
+            zone = get_zone(self.apiclient, self.services)
+            self.services['mode'] = zone.networktype
+
+            #if local storage is enabled, alter the offerings to use localstorage
+            #this step is needed for devcloud
+            if zone.localstorageenabled == True:
+                self.services["service_offerings"]["tiny"]["storagetype"] = 'local'
+
+            template = get_template(
+                                self.apiclient,
+                                zone.id,
+                                self.services["ostype"]
+                                )
+            # Set Zones and disk offerings
+            self.services["small"]["zoneid"] = zone.id
+            self.services["small"]["template"] = template.id
+
+            self.services["iso"]["zoneid"] = zone.id
+            self.services["network"]["zoneid"] = zone.id
+
+            # Create Account, VMs, NAT Rules etc
+            self.account = Account.create(
+                                self.apiclient,
+                                self.services["account"],
+                                domainid=domain.id
+                                )
+            self.cleanup.insert(0, self.account)
+
+            self.service_offering = ServiceOffering.create(
+                                        self.apiclient,
+                                        self.services["service_offerings"]["tiny"]
+                                        )
+            self.cleanup.insert(0, self.service_offering)
+
+            ####################
+            ### Network offering
+            self.network_offering = NetworkOffering.create(
+                                        self.apiclient,
+                                        self.services["network_offering"],
+                                        )
+            self.cleanup.insert(0, self.network_offering)
+            self.network_offering.update(self.apiclient, state='Enabled') # Enable Network offering
+            self.services["network"]["networkoffering"] = self.network_offering.id
+
+            ################
+            ### Test Network
+            self.test_network = Network.create(
+                                                 self.apiclient,
+                                                 self.services["network"],
+                                                 self.account.account.name,
+                                                 self.account.account.domainid,
+                                                 )
+            self.cleanup.insert(0, self.test_network)
+        except Exception as ex:
+            self.debug("Exception during NIC test SETUP!: " + str(ex))
+            self.assertEqual(True, False, "Exception during NIC test SETUP!: " + str(ex))
+
+    @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"])
+    def test_01_nic(self):
+        try:
+            self.virtual_machine = VirtualMachine.create(
+                                        self.apiclient,
+                                        self.services["small"],
+                                        accountid=self.account.account.name,
+                                        domainid=self.account.account.domainid,
+                                        serviceofferingid=self.service_offering.id,
+                                        mode=self.services['mode']
+                                    )
+            self.cleanup.insert(0, self.virtual_machine)
+
+            list_vm_response = list_virtual_machines(
+                                                     self.apiclient,
+                                                     id=self.virtual_machine.id
+                                                     )
+
+            self.debug(
+                    "Verify listVirtualMachines response for virtual machine: %s" \
+                    % self.virtual_machine.id
+                )
+
+            self.assertEqual(
+                                isinstance(list_vm_response, list),
+                                True,
+                                "Check list response returns a valid list"
+                            )
+
+            self.assertNotEqual(
+                                len(list_vm_response),
+                                0,
+                                "Check VM available in List Virtual Machines"
+                            )
+            vm_response = list_vm_response[0]
+
+            self.assertEqual(
+
+                                vm_response.id,
+                                self.virtual_machine.id,
+                                "Check virtual machine id in listVirtualMachines"
+                            )
+
+            self.assertEqual(
+                        vm_response.name,
+                        self.virtual_machine.name,
+                        "Check virtual machine name in listVirtualMachines"
+                        )
+
+            self.assertEqual(
+                        len(vm_response.nic),
+                        1,
+                        "Verify we only start with one nic"
+                        )
+
+            self.assertEqual(
+                vm_response.nic[0].isdefault,
+                True,
+                "Verify initial adapter is set to default"
+            )
+            existing_nic_ip = vm_response.nic[0].ipaddress
+            existing_nic_id = vm_response.nic[0].id
+
+            # 1. add a nic
+            add_response = self.virtual_machine.add_nic(self.apiclient, self.test_network.id)
+
+            time.sleep(5)
+            # now go get the vm list?
+
+            list_vm_response = list_virtual_machines(
+                                                self.apiclient,
+                                                id=self.virtual_machine.id
+                                                )
+
+            self.assertEqual(
+                        len(list_vm_response[0].nic),
+                        2,
+                        "Verify we have 2 NIC's now"
+                        )
+
+            new_nic_id = ""
+            for nc in list_vm_response[0].nic:
+                if nc.ipaddress != existing_nic_ip:
+                    new_nic_id = nc.id
+
+            self.virtual_machine.update_default_nic(self.apiclient, new_nic_id)
+
+            time.sleep(5)
+
+            list_vm_response = list_virtual_machines(
+                                                self.apiclient,
+                                                id=self.virtual_machine.id
+                                                )
+
+            # iterate as we don't know for sure what order our NIC's will be returned to us.
+            for nc in list_vm_response[0].nic:
+                if nc.ipaddress == existing_nic_ip:
+                    self.assertEqual(
+                        nc.isdefault,
+                        False,
+                        "Verify initial adapter is NOT set to default"
+                    )
+                else:
+                    self.assertEqual(
+                        nc.isdefault,
+                        True,
+                        "Verify second adapter is set to default"
+                    )
+
+            sawException = False
+            try:
+                self.virtual_machine.remove_nic(self.apiclient, new_nic_id)
+            except Exception as ex:
+                sawException = True
+
+            self.assertEqual(sawException, True, "Make sure we cannot delete the default NIC")
+
+            self.virtual_machine.remove_nic(self.apiclient, existing_nic_id)
+            time.sleep(5)
+
+            list_vm_response = list_virtual_machines(
+                                                self.apiclient,
+                                                id=self.virtual_machine.id
+                                                )
+
+            self.assertEqual(
+                        len(list_vm_response[0].nic),
+                        1,
+                        "Verify we are back to a signle NIC"
+                        )
+
+            return
+        except Exception as ex:
+            self.debug("Exception during NIC test!: " + str(ex))
+            self.assertEqual(True, False, "Exception during NIC test!: " + str(ex))
+
+    def tearDown(self):
+        if self.cleaning_up == 1:
+            return
+
+        self.cleaning_up = 1
+        try:
+            for obj in self.cleanup:
+                try:
+                    obj.delete(self.apiclient)
+                    time.sleep(10)
+                except Exception as ex:
+                    self.debug("Error deleting: " + str(obj) + ", exception: " + str(ex))
+
+        except Exception as e:
+            self.debug("Warning! Exception in tearDown: %s" % e)
+        self.cleaning_up = 0
+