Merge "Create a Tempest conf from a Devstack env"
diff --git a/tempest/tests/test_list_servers.py b/tempest/tests/test_list_servers.py
index a3f759f..59c31a6 100644
--- a/tempest/tests/test_list_servers.py
+++ b/tempest/tests/test_list_servers.py
@@ -1,6 +1,9 @@
+import unittest2 as unittest
+
+from tempest import exceptions
 from tempest import openstack
 from tempest.common.utils.data_utils import rand_name
-import unittest2 as unittest
+from tempest.tests import utils
 
 
 class ServerDetailsTest(unittest.TestCase):
@@ -15,6 +18,16 @@
         cls.image_ref_alt = cls.config.env.image_ref_alt
         cls.flavor_ref_alt = cls.config.env.flavor_ref_alt
 
+        # Check to see if the alternate image ref actually exists...
+        images_client = cls.os.images_client
+        resp, images = images_client.list_images()
+
+        if any([image for image in images
+                if image['id'] == cls.image_ref_alt]):
+            cls.multiple_images = True
+        else:
+            cls.image_ref_alt = cls.image_ref
+
         cls.s1_name = rand_name('server')
         resp, server = cls.client.create_server(cls.s1_name, cls.image_ref,
                                                 cls.flavor_ref)
@@ -48,6 +61,7 @@
         self.assertTrue(self.s2 in servers)
         self.assertTrue(self.s3 in servers)
 
+    @utils.skip_unless_attr('multiple_images', 'Only one image found')
     def test_list_servers_detailed_filter_by_image(self):
         """Filter the detailed list of servers by image"""
         params = {'image': self.image_ref}
diff --git a/tempest/tests/test_server_metadata.py b/tempest/tests/test_server_metadata.py
index 64bedb9..9e194a2 100644
--- a/tempest/tests/test_server_metadata.py
+++ b/tempest/tests/test_server_metadata.py
@@ -53,6 +53,21 @@
         resp, resp_metadata = self.client.list_server_metadata(self.server_id)
         self.assertEqual(resp_metadata, req_metadata)
 
+    def test_server_create_metadata_key_too_long(self):
+        """
+        Attempt to start a server with a meta-data key that is > 255 characters
+        Try a few values
+        """
+        for sz in [256, 257, 511, 1023]:
+            key = "k" * sz
+            meta = {key: 'data1'}
+            name = rand_name('server')
+            resp, server = self.client.create_server(name, self.image_ref,
+                                                     self.flavor_ref,
+                                                     meta=meta)
+            self.assertEqual(413, resp.status)
+        # no teardown - all creates should fail
+
     def test_update_server_metadata(self):
         """
         The server's metadata values should be updated to the
diff --git a/tempest/tests/utils.py b/tempest/tests/utils.py
new file mode 100644
index 0000000..67fcfdd
--- /dev/null
+++ b/tempest/tests/utils.py
@@ -0,0 +1,73 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack, LLC
+# All Rights Reserved.
+#
+#    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.
+
+"""Common utilities used in testing"""
+
+import nose.plugins.skip
+
+
+class skip_if(object):
+    """Decorator that skips a test if condition is true."""
+    def __init__(self, condition, msg):
+        self.condition = condition
+        self.message = msg
+
+    def __call__(self, func):
+        def _skipper(*args, **kw):
+            """Wrapped skipper function."""
+            if self.condition:
+                raise nose.SkipTest(self.message)
+            func(*args, **kw)
+        _skipper.__name__ = func.__name__
+        _skipper.__doc__ = func.__doc__
+        return _skipper
+
+
+class skip_unless(object):
+    """Decorator that skips a test if condition is not true."""
+    def __init__(self, condition, msg):
+        self.condition = condition
+        self.message = msg
+
+    def __call__(self, func):
+        def _skipper(*args, **kw):
+            """Wrapped skipper function."""
+            if not self.condition:
+                raise nose.SkipTest(self.message)
+            func(*args, **kw)
+        _skipper.__name__ = func.__name__
+        _skipper.__doc__ = func.__doc__
+        return _skipper
+
+
+class skip_unless_attr(object):
+    """Decorator that skips a test if a specified attr exists and is True."""
+    def __init__(self, attr, msg=None):
+        self.attr = attr
+        self.message = msg or ("Test case attribute %s not found "
+                               "or False") % attr
+
+    def __call__(self, func):
+        def _skipper(*args, **kwargs):
+            """Wrapped skipper function."""
+            testobj = args[0]
+            if not getattr(testobj, self.attr, False):
+                raise nose.SkipTest(self.message)
+            func(*args, **kw)
+        _skipper.__name__ = func.__name__
+        _skipper.__doc__ = func.__doc__
+        return _skipper