diff --git a/stress/test_servers.py b/stress/test_servers.py
new file mode 100644
index 0000000..3f62ac3
--- /dev/null
+++ b/stress/test_servers.py
@@ -0,0 +1,342 @@
+# Copyright 2011 Quanta Research Cambridge, Inc.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+"""Defines various sub-classes of the `StressTestCase` and
+`PendingAction` class. The sub-classes of StressTestCase implement various
+API calls on the Nova cluster having to do with creating and deleting VMs.
+Each sub-class will have a corresponding PendingAction. These pending
+actions veriy that the API call was successful or not."""
+
+
+# system imports
+import random
+import time
+
+
+# local imports
+import test_case
+import pending_action
+from tempest.exceptions import TimeoutException
+
+
+class TestCreateVM(test_case.StressTestCase):
+    """Create a virtual machine in the Nova cluster."""
+    _vm_id = 0
+
+    def run(self, manager, state, *pargs, **kwargs):
+        """
+        Send an HTTP POST request to the nova cluster to build a
+        server. Update the state variable to track state of new server
+        and set to PENDING state.
+
+        `manager` : Manager object.
+        `state`      : `State` object describing our view of state of cluster
+        `pargs`      : positional arguments
+        `kwargs`     : keyword arguments, which include:
+                       `key_name`  : name of keypair
+                       `timeout`   : how long to wait before issuing Exception
+                       `image_ref` : index to image types availablexs
+                       `flavor_ref`: index to flavor types available
+                                     (default = 1, which is tiny)
+        """
+
+        # restrict number of instances we can launch
+        if len(state.get_instances()) >= state.get_max_instances():
+            self._logger.debug("maximum number of instances created: %d" %
+                               state.get_max_instances())
+            return None
+
+        _key_name = kwargs.get('key_name', '')
+        _timeout = int(kwargs.get('timeout', 60))
+        _image_ref = kwargs.get('image_ref', manager.config.compute.image_ref)
+        _flavor_ref = kwargs.get('flavor_ref',
+                                 manager.config.compute.flavor_ref)
+
+        expected_server = {
+            'name': 'server' + str(TestCreateVM._vm_id),
+            'metadata': {
+                'key1': 'value1',
+                'key2': 'value2',
+                },
+            'imageRef': _image_ref,
+            'flavorRef': _flavor_ref,
+            'adminPass': 'testpwd',
+            'key_name': _key_name
+            }
+        TestCreateVM._vm_id = TestCreateVM._vm_id + 1
+        response, body = manager.servers_client.create_server(
+                                         expected_server['name'],
+                                         _image_ref,
+                                         _flavor_ref,
+                                         meta=expected_server['metadata'],
+                                         adminPass=expected_server['adminPass']
+                                         )
+
+        if (response.status != 202):
+            self._logger.error("response: %s" % response)
+            self._logger.error("body: %s" % body)
+            raise Exception
+
+        created_server = body
+
+        self._logger.info('setting machine %s to BUILD' %
+                          created_server['id'])
+        state.set_instance_state(created_server['id'],
+                                (created_server, 'BUILD'))
+
+        return VerifyCreateVM(manager,
+                              state,
+                              created_server,
+                              expected_server)
+
+
+class VerifyCreateVM(pending_action.PendingAction):
+    """Verify that VM was built and is running"""
+    def __init__(self, manager,
+                 state,
+                 created_server,
+                 expected_server):
+        super(VerifyCreateVM, self).__init__(manager,
+                                             state,
+                                             created_server,
+                                             )
+        self._expected = expected_server
+
+    def retry(self):
+        """
+        Check to see that the server was created and is running.
+        Update local view of state to indicate that it is running.
+        """
+        # don't run create verification
+        # if target machine has been deleted or is going to be deleted
+        if (self._target['id'] not in self._state.get_instances().keys() or
+            self._state.get_instances()[self._target['id']][1] ==
+            'TERMINATING'):
+            self._logger.info('machine %s is deleted or TERMINATING' %
+                               self._target['id'])
+            return True
+
+        time_diff = time.time() - self._start_time
+        if time_diff > self._timeout:
+            self._logger.error('%d exceeded launch server timeout of %d' %
+                               (time_diff, self._timeout))
+            raise TimeoutException
+
+        admin_pass = self._target['adminPass']
+        # Could check more things here.
+        if (self._expected['adminPass'] != admin_pass):
+            self._logger.error('expected: %s' %
+                               (self._expected['adminPass']))
+            self._logger.error('returned: %s' %
+                               (admin_pass))
+            raise Exception
+
+        if self._check_for_status('ACTIVE') != 'ACTIVE':
+            return False
+
+        self._logger.info('machine %s: BUILD -> ACTIVE [%.1f secs elapsed]' %
+                          (self._target['id'], time.time() - self._start_time))
+        self._state.set_instance_state(self._target['id'],
+                                      (self._target, 'ACTIVE'))
+        return True
+
+
+class TestKillActiveVM(test_case.StressTestCase):
+    """Class to destroy a random ACTIVE server."""
+    def run(self, manager, state, *pargs, **kwargs):
+        """
+        Send an HTTP POST request to the nova cluster to destroy
+        a random ACTIVE server. Update `state` to indicate TERMINATING.
+
+        `manager` : Manager object.
+        `state`      : `State` object describing our view of state of cluster
+        `pargs`      : positional arguments
+        `kwargs`     : keyword arguments, which include:
+                       `timeout` : how long to wait before issuing Exception
+        """
+        # check for active instances
+        vms = state.get_instances()
+        active_vms = [v for k, v in vms.iteritems() if v and v[1] == 'ACTIVE']
+        # no active vms, so return null
+        if not active_vms:
+            self._logger.info('no ACTIVE instances to delete')
+            return
+
+        _timeout = kwargs.get('timeout', 600)
+
+        target = random.choice(active_vms)
+        killtarget = target[0]
+        manager.servers_client.delete_server(killtarget['id'])
+        self._logger.info('machine %s: ACTIVE -> TERMINATING' %
+                          killtarget['id'])
+        state.set_instance_state(killtarget['id'],
+                                (killtarget, 'TERMINATING'))
+        return VerifyKillActiveVM(manager, state,
+                                  killtarget, timeout=_timeout)
+
+
+class VerifyKillActiveVM(pending_action.PendingAction):
+    """Verify that server was destroyed"""
+
+    def retry(self):
+        """
+        Check to see that the server of interest is destroyed. Update
+        state to indicate that server is destroyed by deleting it from local
+        view of state.
+        """
+        tid = self._target['id']
+        # if target machine has been deleted from the state, then it was
+        # already verified to be deleted
+        if (not tid in self._state.get_instances().keys()):
+            return False
+
+        time_diff = time.time() - self._start_time
+        if time_diff > self._timeout:
+            self._logger.error('server %s: %d exceeds terminate timeout %d' %
+                               (tid, time_diff, self._timeout))
+            raise TimeoutException
+
+        try:
+            self._manager.servers_client.get_server(tid)
+        except Exception:
+            # if we get a 404 response, is the machine really gone?
+            target = self._target
+            self._logger.info('machine %s: DELETED [%.1f secs elapsed]' %
+                              (target['id'], time.time() - self._start_time))
+            self._state.delete_machine_state(target['id'])
+            return True
+
+        return False
+
+
+class TestKillAnyVM(test_case.StressTestCase):
+    """Class to destroy a random server regardless of state."""
+
+    def run(self, manager, state, *pargs, **kwargs):
+        """
+        Send an HTTP POST request to the nova cluster to destroy
+        a random server. Update state to TERMINATING.
+
+        `manager` : Manager object.
+        `state`      : `State` object describing our view of state of cluster
+        `pargs`      : positional arguments
+        `kwargs`     : keyword arguments, which include:
+                       `timeout` : how long to wait before issuing Exception
+        """
+
+        vms = state.get_instances()
+        # no vms, so return null
+        if not vms:
+            self._logger.info('no active instances to delete')
+            return
+
+        _timeout = kwargs.get('timeout', 60)
+
+        target = random.choice(vms)
+        killtarget = target[0]
+
+        manager.servers_client.delete_server(killtarget['id'])
+        self._state.set_instance_state(killtarget['id'],
+                                      (killtarget, 'TERMINATING'))
+        # verify object will do the same thing as the active VM
+        return VerifyKillAnyVM(manager, state, killtarget, timeout=_timeout)
+
+VerifyKillAnyVM = VerifyKillActiveVM
+
+
+class TestUpdateVMName(test_case.StressTestCase):
+    """Class to change the name of the active server"""
+    def run(self, manager, state, *pargs, **kwargs):
+        """
+        Issue HTTP POST request to change the name of active server.
+        Update state of server to reflect name changing.
+
+        `manager` : Manager object.
+        `state`      : `State` object describing our view of state of cluster
+        `pargs`      : positional arguments
+        `kwargs`     : keyword arguments, which include:
+                       `timeout`   : how long to wait before issuing Exception
+        """
+
+        # select one machine from active ones
+        vms = state.get_instances()
+        active_vms = [v for k, v in vms.iteritems() if v and v[1] == 'ACTIVE']
+        # no active vms, so return null
+        if not active_vms:
+            self._logger.info('no active instances to update')
+            return
+
+        _timeout = kwargs.get('timeout', 600)
+
+        target = random.choice(active_vms)
+        update_target = target[0]
+
+        # Update name by appending '_updated' to the name
+        new_name = update_target['name'] + '_updated'
+        (response, body) = \
+            manager.servers_client.update_server(update_target['id'],
+                                                    name=new_name)
+        if (response.status != 200):
+            self._logger.error("response: %s " % response)
+            self._logger.error("body: %s " % body)
+            raise Exception
+
+        assert(new_name == body['name'])
+
+        self._logger.info('machine %s: ACTIVE -> UPDATING_NAME' %
+                          body['id'])
+        state.set_instance_state(body['id'],
+                                (body, 'UPDATING_NAME'))
+
+        return VerifyUpdateVMName(manager,
+                                  state,
+                                  body,
+                                  timeout=_timeout)
+
+
+class VerifyUpdateVMName(pending_action.PendingAction):
+    """Check that VM has new name"""
+    def retry(self):
+        """
+        Check that VM has new name. Update local view of `state` to RUNNING.
+        """
+        # don't run update verification
+        # if target machine has been deleted or is going to be deleted
+        if (not self._target['id'] in self._state.get_instances().keys() or
+            self._state.get_instances()[self._target['id']][1] ==
+            'TERMINATING'):
+            return False
+
+        if time.time() - self._start_time > self._timeout:
+            raise TimeoutException
+
+        response, body = \
+            self._manager.serverse_client.get_server(self._target['id'])
+        if (response.status != 200):
+            self._logger.error("response: %s " % response)
+            self._logger.error("body: %s " % body)
+            raise Exception
+
+        if self._target['name'] != body['name']:
+            self._logger.error(self._target['name'] +
+                               ' vs. ' +
+                               body['name'])
+            raise Exception
+
+        # log the update
+        self._logger.info('machine %s: UPDATING_NAME -> ACTIVE' %
+                          self._target['id'])
+        self._state.set_instance_state(self._target['id'],
+                                      (body,
+                                       'ACTIVE'))
+        return True
