summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cloudinit/config/tests/test_snap.py41
-rw-r--r--cloudinit/config/tests/test_ubuntu_advantage.py30
-rw-r--r--cloudinit/tests/helpers.py19
-rw-r--r--tests/unittests/test_handler/test_handler_bootcmd.py42
-rw-r--r--tests/unittests/test_handler/test_handler_runcmd.py48
5 files changed, 104 insertions, 76 deletions
diff --git a/cloudinit/config/tests/test_snap.py b/cloudinit/config/tests/test_snap.py
index 492d2d46..34c80f1e 100644
--- a/cloudinit/config/tests/test_snap.py
+++ b/cloudinit/config/tests/test_snap.py
@@ -9,7 +9,7 @@ from cloudinit.config.cc_snap import (
from cloudinit.config.schema import validate_cloudconfig_schema
from cloudinit import util
from cloudinit.tests.helpers import (
- CiTestCase, mock, wrap_and_call, skipUnlessJsonSchema)
+ CiTestCase, SchemaTestCaseMixin, mock, wrap_and_call, skipUnlessJsonSchema)
SYSTEM_USER_ASSERTION = """\
@@ -245,9 +245,10 @@ class TestRunCommands(CiTestCase):
@skipUnlessJsonSchema()
-class TestSchema(CiTestCase):
+class TestSchema(CiTestCase, SchemaTestCaseMixin):
with_logs = True
+ schema = schema
def test_schema_warns_on_snap_not_as_dict(self):
"""If the snap configuration is not a dict, emit a warning."""
@@ -342,39 +343,27 @@ class TestSchema(CiTestCase):
def test_duplicates_are_fine_array_array(self):
"""Duplicated commands array/array entries are allowed."""
- byebye = ["echo", "bye"]
- try:
- cfg = {'snap': {'commands': [byebye, byebye]}}
- validate_cloudconfig_schema(cfg, schema, strict=True)
- except schema.SchemaValidationError as e:
- self.fail("command entries can be duplicate.")
+ self.assertSchemaValid(
+ {'commands': [["echo", "bye"], ["echo" "bye"]]},
+ "command entries can be duplicate.")
def test_duplicates_are_fine_array_string(self):
"""Duplicated commands array/string entries are allowed."""
- byebye = "echo bye"
- try:
- cfg = {'snap': {'commands': [byebye, byebye]}}
- validate_cloudconfig_schema(cfg, schema, strict=True)
- except schema.SchemaValidationError as e:
- self.fail("command entries can be duplicate.")
+ self.assertSchemaValid(
+ {'commands': ["echo bye", "echo bye"]},
+ "command entries can be duplicate.")
def test_duplicates_are_fine_dict_array(self):
"""Duplicated commands dict/array entries are allowed."""
- byebye = ["echo", "bye"]
- try:
- cfg = {'snap': {'commands': {'00': byebye, '01': byebye}}}
- validate_cloudconfig_schema(cfg, schema, strict=True)
- except schema.SchemaValidationError as e:
- self.fail("command entries can be duplicate.")
+ self.assertSchemaValid(
+ {'commands': {'00': ["echo", "bye"], '01': ["echo", "bye"]}},
+ "command entries can be duplicate.")
def test_duplicates_are_fine_dict_string(self):
"""Duplicated commands dict/string entries are allowed."""
- byebye = "echo bye"
- try:
- cfg = {'snap': {'commands': {'00': byebye, '01': byebye}}}
- validate_cloudconfig_schema(cfg, schema, strict=True)
- except schema.SchemaValidationError as e:
- self.fail("command entries can be duplicate.")
+ self.assertSchemaValid(
+ {'commands': {'00': "echo bye", '01': "echo bye"}},
+ "command entries can be duplicate.")
class TestHandle(CiTestCase):
diff --git a/cloudinit/config/tests/test_ubuntu_advantage.py b/cloudinit/config/tests/test_ubuntu_advantage.py
index f2a59faf..f1beeff8 100644
--- a/cloudinit/config/tests/test_ubuntu_advantage.py
+++ b/cloudinit/config/tests/test_ubuntu_advantage.py
@@ -7,7 +7,8 @@ from cloudinit.config.cc_ubuntu_advantage import (
handle, maybe_install_ua_tools, run_commands, schema)
from cloudinit.config.schema import validate_cloudconfig_schema
from cloudinit import util
-from cloudinit.tests.helpers import CiTestCase, mock, skipUnlessJsonSchema
+from cloudinit.tests.helpers import (
+ CiTestCase, mock, SchemaTestCaseMixin, skipUnlessJsonSchema)
# Module path used in mocks
@@ -105,9 +106,10 @@ class TestRunCommands(CiTestCase):
@skipUnlessJsonSchema()
-class TestSchema(CiTestCase):
+class TestSchema(CiTestCase, SchemaTestCaseMixin):
with_logs = True
+ schema = schema
def test_schema_warns_on_ubuntu_advantage_not_as_dict(self):
"""If ubuntu-advantage configuration is not a dict, emit a warning."""
@@ -169,6 +171,30 @@ class TestSchema(CiTestCase):
{'ubuntu-advantage': {'commands': {'01': 'also valid'}}}, schema)
self.assertEqual('', self.logs.getvalue())
+ def test_duplicates_are_fine_array_array(self):
+ """Duplicated commands array/array entries are allowed."""
+ self.assertSchemaValid(
+ {'commands': [["echo", "bye"], ["echo" "bye"]]},
+ "command entries can be duplicate.")
+
+ def test_duplicates_are_fine_array_string(self):
+ """Duplicated commands array/string entries are allowed."""
+ self.assertSchemaValid(
+ {'commands': ["echo bye", "echo bye"]},
+ "command entries can be duplicate.")
+
+ def test_duplicates_are_fine_dict_array(self):
+ """Duplicated commands dict/array entries are allowed."""
+ self.assertSchemaValid(
+ {'commands': {'00': ["echo", "bye"], '01': ["echo", "bye"]}},
+ "command entries can be duplicate.")
+
+ def test_duplicates_are_fine_dict_string(self):
+ """Duplicated commands dict/string entries are allowed."""
+ self.assertSchemaValid(
+ {'commands': {'00': "echo bye", '01': "echo bye"}},
+ "command entries can be duplicate.")
+
class TestHandle(CiTestCase):
diff --git a/cloudinit/tests/helpers.py b/cloudinit/tests/helpers.py
index 5aada6e7..4999f1f6 100644
--- a/cloudinit/tests/helpers.py
+++ b/cloudinit/tests/helpers.py
@@ -24,6 +24,8 @@ try:
except ImportError:
from ConfigParser import ConfigParser
+from cloudinit.config.schema import (
+ SchemaValidationError, validate_cloudconfig_schema)
from cloudinit import helpers as ch
from cloudinit import util
@@ -312,6 +314,23 @@ class HttprettyTestCase(CiTestCase):
super(HttprettyTestCase, self).tearDown()
+class SchemaTestCaseMixin(unittest2.TestCase):
+
+ def assertSchemaValid(self, cfg, msg="Valid Schema failed validation."):
+ """Assert the config is valid per self.schema.
+
+ If there is only one top level key in the schema properties, then
+ the cfg will be put under that key."""
+ props = list(self.schema.get('properties'))
+ # put cfg under top level key if there is only one in the schema
+ if len(props) == 1:
+ cfg = {props[0]: cfg}
+ try:
+ validate_cloudconfig_schema(cfg, self.schema, strict=True)
+ except SchemaValidationError:
+ self.fail(msg)
+
+
def populate_dir(path, files):
if not os.path.exists(path):
os.makedirs(path)
diff --git a/tests/unittests/test_handler/test_handler_bootcmd.py b/tests/unittests/test_handler/test_handler_bootcmd.py
index c3abedde..b1375269 100644
--- a/tests/unittests/test_handler/test_handler_bootcmd.py
+++ b/tests/unittests/test_handler/test_handler_bootcmd.py
@@ -1,9 +1,10 @@
# This file is part of cloud-init. See LICENSE file for license information.
-from cloudinit.config import cc_bootcmd, schema
+from cloudinit.config.cc_bootcmd import handle, schema
from cloudinit.sources import DataSourceNone
from cloudinit import (distros, helpers, cloud, util)
-from cloudinit.tests.helpers import CiTestCase, mock, skipUnlessJsonSchema
+from cloudinit.tests.helpers import (
+ CiTestCase, mock, SchemaTestCaseMixin, skipUnlessJsonSchema)
import logging
import tempfile
@@ -50,7 +51,7 @@ class TestBootcmd(CiTestCase):
"""When the provided config doesn't contain bootcmd, skip it."""
cfg = {}
mycloud = self._get_cloud('ubuntu')
- cc_bootcmd.handle('notimportant', cfg, mycloud, LOG, None)
+ handle('notimportant', cfg, mycloud, LOG, None)
self.assertIn(
"Skipping module named notimportant, no 'bootcmd' key",
self.logs.getvalue())
@@ -60,7 +61,7 @@ class TestBootcmd(CiTestCase):
invalid_config = {'bootcmd': 1}
cc = self._get_cloud('ubuntu')
with self.assertRaises(TypeError) as context_manager:
- cc_bootcmd.handle('cc_bootcmd', invalid_config, cc, LOG, [])
+ handle('cc_bootcmd', invalid_config, cc, LOG, [])
self.assertIn('Failed to shellify bootcmd', self.logs.getvalue())
self.assertEqual(
"Input to shellify was type 'int'. Expected list or tuple.",
@@ -76,7 +77,7 @@ class TestBootcmd(CiTestCase):
invalid_config = {'bootcmd': 1}
cc = self._get_cloud('ubuntu')
with self.assertRaises(TypeError):
- cc_bootcmd.handle('cc_bootcmd', invalid_config, cc, LOG, [])
+ handle('cc_bootcmd', invalid_config, cc, LOG, [])
self.assertIn(
'Invalid config:\nbootcmd: 1 is not of type \'array\'',
self.logs.getvalue())
@@ -93,7 +94,7 @@ class TestBootcmd(CiTestCase):
'bootcmd': ['ls /', 20, ['wget', 'http://stuff/blah'], {'a': 'n'}]}
cc = self._get_cloud('ubuntu')
with self.assertRaises(TypeError) as context_manager:
- cc_bootcmd.handle('cc_bootcmd', invalid_config, cc, LOG, [])
+ handle('cc_bootcmd', invalid_config, cc, LOG, [])
expected_warnings = [
'bootcmd.1: 20 is not valid under any of the given schemas',
'bootcmd.3: {\'a\': \'n\'} is not valid under any of the given'
@@ -117,7 +118,7 @@ class TestBootcmd(CiTestCase):
'echo {0} $INSTANCE_ID > {1}'.format(my_id, out_file)]}
with mock.patch(self._etmpfile_path, FakeExtendedTempFile):
- cc_bootcmd.handle('cc_bootcmd', valid_config, cc, LOG, [])
+ handle('cc_bootcmd', valid_config, cc, LOG, [])
self.assertEqual(my_id + ' iid-datasource-none\n',
util.load_file(out_file))
@@ -128,7 +129,7 @@ class TestBootcmd(CiTestCase):
with mock.patch(self._etmpfile_path, FakeExtendedTempFile):
with self.assertRaises(util.ProcessExecutionError) as ctxt_manager:
- cc_bootcmd.handle('does-not-matter', valid_config, cc, LOG, [])
+ handle('does-not-matter', valid_config, cc, LOG, [])
self.assertIn(
'Unexpected error while running command.\n'
"Command: ['/bin/sh',",
@@ -138,26 +139,21 @@ class TestBootcmd(CiTestCase):
self.logs.getvalue())
-class TestSchema(CiTestCase):
+@skipUnlessJsonSchema()
+class TestSchema(CiTestCase, SchemaTestCaseMixin):
"""Directly test schema rather than through handle."""
+ schema = schema
+
def test_duplicates_are_fine_array_array(self):
- """Duplicated array entries are allowed."""
- try:
- byebye = ["echo", "bye"]
- schema.validate_cloudconfig_schema(
- {'bootcmd': [byebye, byebye]}, cc_bootcmd.schema, strict=True)
- except schema.SchemaValidationError as e:
- self.fail("runcmd entries as list are allowed to be duplicates.")
+ """Duplicated commands array/array entries are allowed."""
+ self.assertSchemaValid(
+ ["byebye", "byebye"], 'command entries can be duplicate')
def test_duplicates_are_fine_array_string(self):
- """Duplicated array entries entries are allowed in values of array."""
- try:
- byebye = "echo bye"
- schema.validate_cloudconfig_schema(
- {'bootcmd': [byebye, byebye]}, cc_bootcmd.schema, strict=True)
- except schema.SchemaValidationError as e:
- self.fail("runcmd entries are allowed to be duplicates.")
+ """Duplicated commands array/string entries are allowed."""
+ self.assertSchemaValid(
+ ["echo bye", "echo bye"], "command entries can be duplicate.")
# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_runcmd.py b/tests/unittests/test_handler/test_handler_runcmd.py
index ee1981d1..9ce334ac 100644
--- a/tests/unittests/test_handler/test_handler_runcmd.py
+++ b/tests/unittests/test_handler/test_handler_runcmd.py
@@ -1,10 +1,11 @@
# This file is part of cloud-init. See LICENSE file for license information.
-from cloudinit.config import cc_runcmd, schema
+from cloudinit.config.cc_runcmd import handle, schema
from cloudinit.sources import DataSourceNone
from cloudinit import (distros, helpers, cloud, util)
from cloudinit.tests.helpers import (
- CiTestCase, FilesystemMockingTestCase, skipUnlessJsonSchema)
+ CiTestCase, FilesystemMockingTestCase, SchemaTestCaseMixin,
+ skipUnlessJsonSchema)
import logging
import os
@@ -35,7 +36,7 @@ class TestRuncmd(FilesystemMockingTestCase):
"""When the provided config doesn't contain runcmd, skip it."""
cfg = {}
mycloud = self._get_cloud('ubuntu')
- cc_runcmd.handle('notimportant', cfg, mycloud, LOG, None)
+ handle('notimportant', cfg, mycloud, LOG, None)
self.assertIn(
"Skipping module named notimportant, no 'runcmd' key",
self.logs.getvalue())
@@ -44,7 +45,7 @@ class TestRuncmd(FilesystemMockingTestCase):
"""Commands which can't be converted to shell will raise errors."""
invalid_config = {'runcmd': 1}
cc = self._get_cloud('ubuntu')
- cc_runcmd.handle('cc_runcmd', invalid_config, cc, LOG, [])
+ handle('cc_runcmd', invalid_config, cc, LOG, [])
self.assertIn(
'Failed to shellify 1 into file'
' /var/lib/cloud/instances/iid-datasource-none/scripts/runcmd',
@@ -59,7 +60,7 @@ class TestRuncmd(FilesystemMockingTestCase):
"""
invalid_config = {'runcmd': 1}
cc = self._get_cloud('ubuntu')
- cc_runcmd.handle('cc_runcmd', invalid_config, cc, LOG, [])
+ handle('cc_runcmd', invalid_config, cc, LOG, [])
self.assertIn(
'Invalid config:\nruncmd: 1 is not of type \'array\'',
self.logs.getvalue())
@@ -75,7 +76,7 @@ class TestRuncmd(FilesystemMockingTestCase):
invalid_config = {
'runcmd': ['ls /', 20, ['wget', 'http://stuff/blah'], {'a': 'n'}]}
cc = self._get_cloud('ubuntu')
- cc_runcmd.handle('cc_runcmd', invalid_config, cc, LOG, [])
+ handle('cc_runcmd', invalid_config, cc, LOG, [])
expected_warnings = [
'runcmd.1: 20 is not valid under any of the given schemas',
'runcmd.3: {\'a\': \'n\'} is not valid under any of the given'
@@ -90,7 +91,7 @@ class TestRuncmd(FilesystemMockingTestCase):
"""Valid runcmd schema is written to a runcmd shell script."""
valid_config = {'runcmd': [['ls', '/']]}
cc = self._get_cloud('ubuntu')
- cc_runcmd.handle('cc_runcmd', valid_config, cc, LOG, [])
+ handle('cc_runcmd', valid_config, cc, LOG, [])
runcmd_file = os.path.join(
self.new_root,
'var/lib/cloud/instances/iid-datasource-none/scripts/runcmd')
@@ -99,25 +100,22 @@ class TestRuncmd(FilesystemMockingTestCase):
self.assertEqual(0o700, stat.S_IMODE(file_stat.st_mode))
-class TestSchema(CiTestCase):
+@skipUnlessJsonSchema()
+class TestSchema(CiTestCase, SchemaTestCaseMixin):
"""Directly test schema rather than through handle."""
- def test_duplicates_are_fine_array(self):
- """Duplicated array entries are allowed."""
- try:
- byebye = ["echo", "bye"]
- schema.validate_cloudconfig_schema(
- {'runcmd': [byebye, byebye]}, cc_runcmd.schema, strict=True)
- except schema.SchemaValidationError as e:
- self.fail("runcmd entries as list are allowed to be duplicates.")
-
- def test_duplicates_are_fine_string(self):
- """Duplicated string entries are allowed."""
- try:
- byebye = "echo bye"
- schema.validate_cloudconfig_schema(
- {'runcmd': [byebye, byebye]}, cc_runcmd.schema, strict=True)
- except schema.SchemaValidationError as e:
- self.fail("runcmd entries are allowed to be duplicates.")
+ schema = schema
+
+ def test_duplicates_are_fine_array_array(self):
+ """Duplicated commands array/array entries are allowed."""
+ self.assertSchemaValid(
+ [["echo", "bye"], ["echo", "bye"]],
+ "command entries can be duplicate.")
+
+ def test_duplicates_are_fine_array_string(self):
+ """Duplicated commands array/string entries are allowed."""
+ self.assertSchemaValid(
+ ["echo bye", "echo bye"],
+ "command entries can be duplicate.")
# vi: ts=4 expandtab