test case for observer containers
diff --git a/xos/tosca/tests/allObserverTests.py b/xos/tosca/tests/allObserverTests.py
index c7470ac..6a566a9 100644
--- a/xos/tosca/tests/allObserverTests.py
+++ b/xos/tosca/tests/allObserverTests.py
@@ -1,4 +1,5 @@
 from observerVMTest import ObserverVMTest
+from observerContainerTest import ObserverContainerTest
 from observerImageTest import ObserverImageTest
 from observerUserTest import ObserverUserTest
 from observerSiteTest import ObserverSiteTest
@@ -6,6 +7,7 @@
 
 if __name__ == "__main__":
     ObserverVMTest()
+    ObserverContainerTest()
     ObserverImageTest()
     ObserverSiteTest()
     ObserverUserTest()
diff --git a/xos/tosca/tests/basetest.py b/xos/tosca/tests/basetest.py
index f7f04eb..d9701d7 100644
--- a/xos/tosca/tests/basetest.py
+++ b/xos/tosca/tests/basetest.py
@@ -67,15 +67,23 @@
 
         return yml
 
-    def make_compute(self, slice, name, caps={}, props={}, reqs=[], num_cpus="1", disk_size="10 GB", mem_size="4 MB"):
+    def make_compute(self, slice, name, caps={}, props={}, reqs=[], num_cpus="1", disk_size="10 GB", mem_size="4 MB", isolation="vm"):
         reqs = reqs[:]
+        props = props.copy()
         caps = caps.copy()
 
+        if isolation=="container":
+            type = "tosca.nodes.Compute.Container"
+        elif isolation=="container_vm":
+            type = "tosca.nodes.Compute.ContainerVM"
+        else:
+            type = "tosca.nodes.Compute"
+
         caps.update( {"host": {"num_cpus": num_cpus, "disk_size": disk_size, "mem_size": mem_size},
                       "os": {"architecture": "x86_64", "type": "linux", "distribution": "rhel", "version": "6.5"}} )
         reqs.append( (slice, "tosca.relationships.MemberOfSlice") )
 
-        return self.make_nodetemplate(name, "tosca.nodes.Compute",
+        return self.make_nodetemplate(name, type,
                                       caps= caps,
                                       props = props,
                                       reqs= reqs)
diff --git a/xos/tosca/tests/observerContainerTest.py b/xos/tosca/tests/observerContainerTest.py
new file mode 100644
index 0000000..a31b866
--- /dev/null
+++ b/xos/tosca/tests/observerContainerTest.py
@@ -0,0 +1,95 @@
+from observertest import BaseObserverToscaTest
+
+from core.models import Instance, Site
+
+# Note that as a side effect, these tests will also create a Site
+
+class ObserverContainerTest(BaseObserverToscaTest):
+    tests = ["create_container"]
+    # hide_observer_output = False # uncomment to display lots of stuff to screen
+
+    def cleanup(self):
+        # We don't want to leak resources, so we make sure to let the observer
+        # attempt to delete these objects.
+        self.try_to_delete(Instance, purge=False, name="test_compute1")
+        self.try_to_delete(Site, purge=False, name="testsite")
+        self.run_observer()
+        # The site objects don't seem to go away nicely, they linger about and
+        # cause an IntegrityError due to a duplicate login_base
+        self.try_to_delete(Site, purge=True, name="testsite")
+
+    def get_base_templates(self):
+        return self.make_nodetemplate("testsite", "tosca.nodes.Site") + \
+               self.make_nodetemplate("testsite_slice1", "tosca.nodes.Slice", reqs=[("testsite", "tosca.relationships.MemberOfSite")]) + \
+               self.make_nodetemplate("andybavier/docker-vcpe", "tosca.nodes.Image", props={"kind": "container", "container_format": "na", "disk_format": "na"})
+
+    def create_container(self):
+        self.assert_noobj(Instance, "test_compute1")
+        self.execute(self.get_base_templates() +
+                     self.make_compute("testsite_slice1", "test_compute1", disk_size="1 GB", mem_size="513 MB", isolation="container",
+                                       reqs=[("andybavier/docker-vcpe", "tosca.relationships.UsesImage")],
+                                       ))
+        instance = self.assert_obj(Instance, "test_compute1")
+        assert(instance.flavor.name == "m1.small")
+
+        # first pass makes the Networks
+        self.run_model_policy(save_output="/tmp/instancetest:create_container:model_policy_first")
+
+        # XXX deal with bug where
+        instance = self.assert_obj(Instance, "test_compute1")
+        instance.save()
+
+        # second pass makes the NetworkControllers
+        self.run_model_policy(save_output="/tmp/instancetest:create_container:model_policy_second")
+
+        # first observer pass should make any necessary networks or ports
+        self.run_observer(save_output="/tmp/instancetest:create_container:observer_first")
+
+        # reset the exponential backoff
+        instance = self.assert_obj(Instance, "test_compute1")
+        instance.backend_register="{}"
+        instance.save()
+
+        # we need to reset the companion instance's exponential backoff too
+        companion_instance = Instance.objects.filter(slice=instance.slice, isolation="vm")
+        assert(companion_instance)
+        companion_instance = companion_instance[0]
+        companion_instance.backend_register="{}"
+        companion_instance.save()
+
+        # third pass reset lazy_blocked
+        self.run_model_policy(save_output="/tmp/instancetest:create_container:model_policy_third")
+
+        # second observer pass should instantiate the controller networks
+        #    (might instantiate the instance, too)
+        self.run_observer(save_output="/tmp/instancetest:create_container:observer_second")
+
+        # reset the exponential backoff
+        instance = self.assert_obj(Instance, "test_compute1")
+        instance.backend_register="{}"
+        instance.save()
+
+        # we need to reset the companion instance's exponential backoff too
+        companion_instance = Instance.objects.filter(slice=instance.slice, isolation="vm")
+        assert(companion_instance)
+        companion_instance = companion_instance[0]
+        companion_instance.backend_register="{}"
+        companion_instance.save()
+
+        # third observer pass should instantiate the companion instance
+        self.run_observer(save_output="/tmp/instancetest:create_container:observer_third")
+
+        # third observer pass should instantiate the instance
+        self.run_observer(save_output="/tmp/instancetest:create_container:observer_fourth")
+
+        instance = self.assert_obj(Instance, "test_compute1")
+
+        assert(instance.instance_id is not None)
+        assert(instance.instance_name is not None)
+
+        # there should be one port on the private network
+        assert(instance.ports.count() == 1)
+
+if __name__ == "__main__":
+    ObserverContainerTest()
+
diff --git a/xos/tosca/tests/observerVMTest.py b/xos/tosca/tests/observerVMTest.py
index f385090..65cbde5 100644
--- a/xos/tosca/tests/observerVMTest.py
+++ b/xos/tosca/tests/observerVMTest.py
@@ -5,7 +5,7 @@
 # Note that as a side effect, these tests will also create a Site
 
 class ObserverVMTest(BaseObserverToscaTest):
-    tests = ["create_instance"]
+    tests = ["create_vm"]
     # hide_observer_output = False # uncomment to display lots of stuff to screen
 
     def cleanup(self):
@@ -22,7 +22,7 @@
         return self.make_nodetemplate("testsite", "tosca.nodes.Site") + \
                self.make_nodetemplate("testsite_slice1", "tosca.nodes.Slice", reqs=[("testsite", "tosca.relationships.MemberOfSite")])
 
-    def create_instance(self):
+    def create_vm(self):
         self.assert_noobj(Instance, "test_compute1")
         self.execute(self.get_base_templates() +
                      self.make_compute("testsite_slice1", "test_compute1", disk_size="1 GB", mem_size="513 MB"))
@@ -30,13 +30,13 @@
         assert(instance.flavor.name == "m1.small")
 
         # first pass makes the Networks
-        self.run_model_policy(save_output="/tmp/instancetest:create_instance:model_policy_first")
+        self.run_model_policy(save_output="/tmp/instancetest:create_vm:model_policy_first")
 
         # second pass makes the NetworkControllers
-        self.run_model_policy(save_output="/tmp/instancetest:create_instance:model_policy_second")
+        self.run_model_policy(save_output="/tmp/instancetest:create_vm:model_policy_second")
 
         # first observer pass should make any necessary networks or ports
-        self.run_observer(save_output="/tmp/instancetest:create_instance:observer_first")
+        self.run_observer(save_output="/tmp/instancetest:create_vm:observer_first")
 
         # reset the exponential backoff
         instance = self.assert_obj(Instance, "test_compute1")
@@ -44,11 +44,11 @@
         instance.save()
 
         # third pass reset lazy_blocked
-        self.run_model_policy(save_output="/tmp/instancetest:create_instance:model_policy_third")
+        self.run_model_policy(save_output="/tmp/instancetest:create_vm:model_policy_third")
 
         # second observer pass should instantiate the controller networks
         #    (might instantiate the instance, too)
-        self.run_observer(save_output="/tmp/instancetest:create_instance:observer_second")
+        self.run_observer(save_output="/tmp/instancetest:create_vm:observer_second")
 
         # reset the exponential backoff
         instance = self.assert_obj(Instance, "test_compute1")
@@ -56,13 +56,16 @@
         instance.save()
 
         # third observer pass should instantiate the instance
-        self.run_observer(save_output="/tmp/instancetest:create_instance:observer_third")
+        self.run_observer(save_output="/tmp/instancetest:create_vm:observer_third")
 
         instance = self.assert_obj(Instance, "test_compute1")
 
         assert(instance.instance_id is not None)
         assert(instance.instance_name is not None)
 
+        # there should be a port on the private network and a port on nat-net
+        assert(instance.ports.count() == 2)
+
 if __name__ == "__main__":
     ObserverVMTest()