From 39b5a876fe88c26a5d0fccf8846d92b31bcb11e1 Mon Sep 17 00:00:00 2001 From: Felipe Monteiro Date: Mon, 22 Jan 2018 19:31:06 +0000 Subject: [PATCH] Add unit tests for Manifest handler Change-Id: Ia7e1c0861cb79b78a65ad95f50729a85a874a892 --- armada/handlers/manifest.py | 76 +++++++ armada/tests/unit/handlers/test_manifest.py | 229 +++++++++++++++++++- armada/tests/unit/handlers/test_tiller.py | 14 ++ examples/simple.yaml | 1 - 4 files changed, 313 insertions(+), 7 deletions(-) diff --git a/armada/handlers/manifest.py b/armada/handlers/manifest.py index 63315909..f6597754 100644 --- a/armada/handlers/manifest.py +++ b/armada/handlers/manifest.py @@ -71,6 +71,19 @@ class Manifest(object): details=error % expected_schemas) def _find_documents(self, target_manifest=None): + """Returns the chart documents, chart group documents, + and armada manifest + + If multiple documents with schema "armada/Manifest/v1" are provided, + specify ``target_manifest`` to select the target one. + + :param str target_manifest: The target manifest to use when multiple + documents with "armada/Manifest/v1" are contained in + ``documents``. Default is None. + :returns: Tuple of chart documents, chart groups, and manifests + found in ``self.documents`` + :rtype: tuple + """ charts = [] groups = [] manifests = [] @@ -89,6 +102,14 @@ class Manifest(object): return charts, groups, manifests def find_chart_document(self, name): + """Returns a chart document with the specified name + + :param str name: name of the desired chart document + :returns: The requested chart document + :rtype: dict + :raises ManifestException: If a chart document with the + specified name is not found + """ for chart in self.charts: if chart.get('metadata', {}).get('name') == name: return chart @@ -97,6 +118,14 @@ class Manifest(object): const.DOCUMENT_CHART, name)) def find_chart_group_document(self, name): + """Returns a chart group document with the specified name + + :param str name: name of the desired chart group document + :returns: The requested chart group document + :rtype: dict + :raises ManifestException: If a chart + group document with the specified name is not found + """ for group in self.groups: if group.get('metadata', {}).get('name') == name: return group @@ -105,14 +134,31 @@ class Manifest(object): const.DOCUMENT_GROUP, name)) def build_charts_deps(self): + """Build chart dependencies for every ``chart``. + + :returns: None + """ for chart in self.charts: self.build_chart_deps(chart) def build_chart_groups(self): + """Build chart dependencies for every ``chart_group``. + + :returns: None + """ for chart_group in self.groups: self.build_chart_group(chart_group) def build_chart_deps(self, chart): + """Recursively build chart dependencies for ``chart``. + + :param dict chart: The chart whose dependencies will be recursively + built. + :returns: The chart with all dependencies. + :rtype: dict + :raises ManifestException: If a chart for a dependency name listed + under ``chart['data']['dependencies']`` could not be found. + """ try: dep = None for iter, dep in enumerate(chart.get('data').get('dependencies')): @@ -127,8 +173,19 @@ class Manifest(object): raise exceptions.ManifestException( details="Could not find dependency chart {} in {}".format( dep, const.DOCUMENT_CHART)) + else: + return chart def build_chart_group(self, chart_group): + """Builds the chart dependencies for`charts`chart group``. + + :param dict chart_group: The chart_group whose dependencies + will be built. + :returns: The chart_group with all dependencies. + :rtype: dict + :raises ManifestException: If a chart for a dependency name listed + under ``chart_group['data']['chart_group']`` could not be found. + """ try: chart = None for iter, chart in enumerate(chart_group.get('data').get( @@ -143,8 +200,18 @@ class Manifest(object): raise exceptions.ManifestException( details="Could not find chart {} in {}".format( chart, const.DOCUMENT_GROUP)) + else: + return chart_group def build_armada_manifest(self): + """Builds the armmada manifest while pulling out data + from the chart_group. + + :returns: The armada manifest with the data of the chart groups. + :rtype: dict + :raises ManifestException: If a chart group's data listed + under ``chart_group['data']`` could not be found. + """ try: group = None for iter, group in enumerate(self.manifest.get('data').get( @@ -162,8 +229,17 @@ class Manifest(object): raise exceptions.ManifestException( "Could not find chart group {} in {}".format( group, const.DOCUMENT_MANIFEST)) + else: + return self.manifest def get_manifest(self): + """Builds all of the documents including the dependencies of the + chart documents, the charts in the chart_groups, and the + armada manifest + + :returns: The armada manifest. + :rtype: dict + """ self.build_charts_deps() self.build_chart_groups() self.build_armada_manifest() diff --git a/armada/tests/unit/handlers/test_manifest.py b/armada/tests/unit/handlers/test_manifest.py index cb3c79ee..1cc8826a 100644 --- a/armada/tests/unit/handlers/test_manifest.py +++ b/armada/tests/unit/handlers/test_manifest.py @@ -105,15 +105,232 @@ class ManifestTestCase(testtools.TestCase): self.assertEqual('alt-armada-manifest', armada_manifest.manifest['metadata']['name']) - def test_find_chart_document(self): + def test_get_manifest(self): armada_manifest = manifest.Manifest(self.documents) - chart = armada_manifest.find_chart_document('helm-toolkit') - self.assertEqual(self.documents[0], chart) + obtained_manifest = armada_manifest.get_manifest() + self.assertIsInstance(obtained_manifest, dict) + self.assertEqual(obtained_manifest['armada'], + armada_manifest.manifest['data']) - def test_find_group_document(self): + def test_find_documents(self): armada_manifest = manifest.Manifest(self.documents) - chart = armada_manifest.find_chart_group_document('openstack-keystone') - self.assertEqual(self.documents[-2], chart) + chart_documents, chart_groups, manifests = armada_manifest. \ + _find_documents() + + # checking if all the chart documents are present + self.assertIsInstance(chart_documents, list) + + helm_toolkit_chart = armada_manifest. \ + find_chart_document('helm-toolkit') + self.assertEqual(chart_documents[0], helm_toolkit_chart) + + mariadb_chart = armada_manifest.find_chart_document('mariadb') + self.assertEqual(chart_documents[1], mariadb_chart) + + memcached_chart = armada_manifest.find_chart_document('memcached') + self.assertEqual(chart_documents[2], memcached_chart) + + keystone_chart = armada_manifest.find_chart_document('keystone') + self.assertEqual(chart_documents[3], keystone_chart) + + # checking if all the chart group documents are present + self.assertIsInstance(chart_groups, list) + + keystone_infra_services_chart_group = armada_manifest. \ + find_chart_group_document('keystone-infra-services') + self.assertEqual(chart_groups[0], + keystone_infra_services_chart_group) + + openstack_keystone_chart_group = armada_manifest. \ + find_chart_group_document('openstack-keystone') + self.assertEqual(chart_groups[1], openstack_keystone_chart_group) + + # verifying the manifests + self.assertIsInstance(manifests, list) + + self.assertEqual(manifests[0], armada_manifest.manifest) + + def test_verify_chart_documents(self): + armada_manifest = manifest.Manifest(self.documents) + helm_toolkit_chart = armada_manifest. \ + find_chart_document('helm-toolkit') + self.assertIsInstance(helm_toolkit_chart, dict) + self.assertEqual(self.documents[0], helm_toolkit_chart) + + mariadb_chart = armada_manifest.find_chart_document('mariadb') + self.assertIsInstance(mariadb_chart, dict) + self.assertEqual(self.documents[1], mariadb_chart) + + memcached_chart = armada_manifest.find_chart_document('memcached') + self.assertIsInstance(memcached_chart, dict) + self.assertEqual(self.documents[2], memcached_chart) + + keystone_chart = armada_manifest.find_chart_document('keystone') + self.assertIsInstance(keystone_chart, dict) + self.assertEqual(self.documents[3], keystone_chart) + + def test_verify_chart_group_documents(self): + armada_manifest = manifest.Manifest(self.documents) + ok_chart = armada_manifest. \ + find_chart_group_document('openstack-keystone') + self.assertIsInstance(ok_chart, dict) + self.assertEqual(self.documents[-2], ok_chart) + + armada_manifest = manifest.Manifest(self.documents) + kis_chart = armada_manifest.find_chart_group_document( + 'keystone-infra-services') + self.assertIsInstance(kis_chart, dict) + self.assertEqual(self.documents[-3], kis_chart) + + def test_verify_build_armada_manifest(self): + armada_manifest = manifest.Manifest(self.documents) + + built_armada_manifest = armada_manifest.build_armada_manifest() + + self.assertIsNotNone(built_armada_manifest) + self.assertIsInstance(built_armada_manifest, dict) + + # the first chart group in the armada manifest + keystone_infra_services_chart_group = armada_manifest. \ + find_chart_group_document('keystone-infra-services') + keystone_infra_services_chart_group_data = \ + keystone_infra_services_chart_group.get('data') + + self.assertEqual(keystone_infra_services_chart_group_data, + built_armada_manifest['data']['chart_groups'][0]) + + # the first chart group in the armada manifest + openstack_keystone_chart_group = armada_manifest. \ + find_chart_group_document('openstack-keystone') + openstack_keystone_chart_group_data = \ + openstack_keystone_chart_group.get('data') + + self.assertEqual(openstack_keystone_chart_group_data, + built_armada_manifest['data']['chart_groups'][1]) + + def test_verify_build_chart_group_deps(self): + armada_manifest = manifest.Manifest(self.documents) + # building the deps for openstack-keystone chart group + chart_group = armada_manifest.find_chart_group_document( + 'openstack-keystone') + openstack_keystone_chart_group_deps = armada_manifest. \ + build_chart_group(chart_group) + openstack_keystone_chart_group_deps_dep_added = \ + openstack_keystone_chart_group_deps[ + 'data']['chart_group'][0]['chart']['dependencies'] + + # keystone chart dependencies + keystone_chart = armada_manifest.find_chart_document('keystone') + keystone_chart_with_deps = armada_manifest.build_chart_deps( + keystone_chart) + keystone_dependencies = keystone_chart_with_deps[ + 'data']['dependencies'] + + self.assertEqual(openstack_keystone_chart_group_deps_dep_added[0], + keystone_dependencies[0]) + + # building the deps for openstack-keystone chart group + chart_group = armada_manifest.find_chart_group_document( + 'keystone-infra-services') + openstack_keystone_chart_group_deps = armada_manifest. \ + build_chart_group(chart_group) + keystone_infra_services_dep_added = \ + openstack_keystone_chart_group_deps[ + 'data']['chart_group'][0]['chart']['dependencies'] + + # building mariadb chart dependencies + mariadb_chart = armada_manifest.find_chart_document('mariadb') + mariadb_chart_with_deps = armada_manifest.build_chart_deps( + mariadb_chart) + mariadb_dependencies = mariadb_chart_with_deps[ + 'data']['dependencies'] + + # building memcached chart dependencies + memcached_chart = armada_manifest.find_chart_document('memcached') + memcached_chart_with_deps = armada_manifest.build_chart_deps( + memcached_chart) + memcached_dependencies = memcached_chart_with_deps[ + 'data']['dependencies'] + + self.assertEqual(keystone_infra_services_dep_added[0], + mariadb_dependencies[0]) + self.assertEqual(keystone_infra_services_dep_added[0], + memcached_dependencies[0]) + + def test_verify_build_chart_deps(self): + armada_manifest = manifest.Manifest(self.documents) + + # helm-toolkit chart + helm_toolkit_chart = armada_manifest.find_chart_document( + 'helm-toolkit') + helm_toolkit_original_dependency = helm_toolkit_chart.get('data') + helm_toolkit_chart_with_deps = armada_manifest.build_chart_deps( + helm_toolkit_chart).get('data') + + # since not dependent on other charts, the original and modified + # dependencies are the same + self.assertEqual(helm_toolkit_original_dependency, + helm_toolkit_chart_with_deps) + + # helm-toolkit dependency, the basis for comparison of d + # ependencies in other charts + expected_helm_toolkit_dependency = {'chart': helm_toolkit_chart.get( + 'data')} + + # keystone chart dependencies + keystone_chart = armada_manifest.find_chart_document('keystone') + original_keystone_chart = copy.deepcopy(keystone_chart) + keystone_chart_with_deps = armada_manifest.build_chart_deps( + keystone_chart) + + self.assertNotEqual(original_keystone_chart, keystone_chart_with_deps) + self.assertIn('data', keystone_chart_with_deps) + self.assertIn('dependencies', keystone_chart_with_deps['data']) + + keystone_dependencies = keystone_chart_with_deps[ + 'data']['dependencies'] + self.assertIsInstance(keystone_dependencies, list) + self.assertEqual(1, len(keystone_dependencies)) + + self.assertEqual(expected_helm_toolkit_dependency, + keystone_dependencies[0]) + + # mariadb chart dependencies + mariadb_chart = armada_manifest.find_chart_document('mariadb') + original_mariadb_chart = copy.deepcopy(mariadb_chart) + mariadb_chart_with_deps = armada_manifest.build_chart_deps( + mariadb_chart) + + self.assertNotEqual(original_mariadb_chart, mariadb_chart_with_deps) + self.assertIn('data', mariadb_chart_with_deps) + self.assertIn('dependencies', mariadb_chart_with_deps['data']) + + mariadb_dependencies = mariadb_chart_with_deps[ + 'data']['dependencies'] + self.assertIsInstance(mariadb_dependencies, list) + self.assertEqual(1, len(mariadb_dependencies)) + + self.assertEqual(expected_helm_toolkit_dependency, + mariadb_dependencies[0]) + + # memcached chart dependencies + memcached_chart = armada_manifest.find_chart_document('memcached') + original_memcached_chart = copy.deepcopy(memcached_chart) + memcached_chart_with_deps = armada_manifest.build_chart_deps( + memcached_chart) + + self.assertNotEqual(original_memcached_chart, + memcached_chart_with_deps) + self.assertIn('data', memcached_chart_with_deps) + self.assertIn('dependencies', memcached_chart_with_deps['data']) + + memcached_dependencies = memcached_chart_with_deps[ + 'data']['dependencies'] + self.assertIsInstance(memcached_dependencies, list) + self.assertEqual(1, len(memcached_dependencies)) + + self.assertEqual(expected_helm_toolkit_dependency, + memcached_dependencies[0]) class ManifestNegativeTestCase(testtools.TestCase): diff --git a/armada/tests/unit/handlers/test_tiller.py b/armada/tests/unit/handlers/test_tiller.py index 93540fa0..bea18c5f 100644 --- a/armada/tests/unit/handlers/test_tiller.py +++ b/armada/tests/unit/handlers/test_tiller.py @@ -1,3 +1,17 @@ +# Copyright 2017 The Armada Authors. +# +# 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. + import mock import unittest diff --git a/examples/simple.yaml b/examples/simple.yaml index ee7d2260..fcf87075 100644 --- a/examples/simple.yaml +++ b/examples/simple.yaml @@ -1,4 +1,3 @@ -# simple deploy --- schema: armada/Chart/v1 metadata: