diff --git a/armada/api/controller/test.py b/armada/api/controller/test.py index a3c573ae..4f621402 100644 --- a/armada/api/controller/test.py +++ b/armada/api/controller/test.py @@ -20,9 +20,8 @@ from oslo_config import cfg from armada import api from armada.common import policy -from armada import const from armada.handlers.lock import lock_and_thread, LockException -from armada.handlers.manifest import Manifest +from armada.handlers.manifest import ManifestHelper from armada.handlers.test import Test from armada.utils.release import release_prefixer from armada.utils import validate @@ -130,40 +129,35 @@ class TestReleasesManifestController(api.BaseResource): if not is_valid: return - armada_obj = Manifest( - documents, target_manifest=target_manifest).get_manifest() - - prefix = armada_obj[const.KEYWORD_DATA][const.KEYWORD_PREFIX] known_releases = [release[0] for release in tiller.list_charts()] + manifest_helper = ManifestHelper( + documents, target_manifest=target_manifest) + prefix = manifest_helper.get_release_prefix() + message = {'tests': {'passed': [], 'skipped': [], 'failed': []}} + for chart in manifest_helper.get_charts(): + release_name = release_prefixer(prefix, chart.get('release')) + if release_name in known_releases: + cleanup = req.get_param_as_bool('cleanup') + enable_all = req.get_param_as_bool('enable_all') + cg_test_charts = group.get('test_charts') - for group in armada_obj.get(const.KEYWORD_DATA).get( - const.KEYWORD_GROUPS): - for ch in group.get(const.KEYWORD_CHARTS): - chart = ch['chart'] + test_handler = Test( + chart, + release_name, + tiller, + cg_test_charts=cg_test_charts, + cleanup=cleanup, + enable_all=enable_all) - release_name = release_prefixer(prefix, chart.get('release')) - if release_name in known_releases: - cleanup = req.get_param_as_bool('cleanup') - enable_all = req.get_param_as_bool('enable_all') - cg_test_charts = group.get('test_charts') + if test_handler.test_enabled: + success = test_handler.test_release_for_success() - test_handler = Test( - chart, - release_name, - tiller, - cg_test_charts=cg_test_charts, - cleanup=cleanup, - enable_all=enable_all) - - if test_handler.test_enabled: - success = test_handler.test_release_for_success() - - if success: - message['test']['passed'].append(release_name) - else: - message['test']['failed'].append(release_name) + if success: + message['test']['passed'].append(release_name) + else: + message['test']['failed'].append(release_name) else: self.logger.info('Release %s not found - SKIPPING', release_name) diff --git a/armada/cli/delete.py b/armada/cli/delete.py index bfb755d8..5ea3cf6a 100644 --- a/armada/cli/delete.py +++ b/armada/cli/delete.py @@ -18,10 +18,9 @@ import click from oslo_config import cfg from armada.cli import CliAction -from armada import const from armada.handlers.chart_delete import ChartDelete from armada.handlers.lock import lock_and_thread -from armada.handlers.manifest import Manifest +from armada.handlers.manifest import ManifestHelper from armada.handlers.tiller import Tiller from armada.utils.release import release_prefixer @@ -125,19 +124,14 @@ class DeleteChartManifest(CliAction): with open(self.manifest) as f: documents = list(yaml.safe_load_all(f.read())) try: - armada_obj = Manifest(documents).get_manifest() - prefix = armada_obj.get(const.KEYWORD_DATA).get( - const.KEYWORD_PREFIX) + manifest_helper = ManifestHelper(documents) + prefix = manifest_helper.get_release_prefix() - for group in armada_obj.get(const.KEYWORD_DATA).get( - const.KEYWORD_GROUPS): - for ch in group.get(const.KEYWORD_DATA).get( - const.KEYWORD_CHARTS): - chart = ch.get(const.KEYWORD_DATA) - release_name = release_prefixer( - prefix, chart.get('release')) - if release_name in known_release_names: - target_deletes.append((chart, release_name)) + for chart in manifest_helper.get_charts(): + release_name = release_prefixer(prefix, + chart.get('release')) + if release_name in known_release_names: + target_deletes.append((chart, release_name)) except yaml.YAMLError as e: mark = e.problem_mark self.logger.info( diff --git a/armada/cli/test.py b/armada/cli/test.py index 55611805..b58de9a7 100644 --- a/armada/cli/test.py +++ b/armada/cli/test.py @@ -18,9 +18,8 @@ import click from oslo_config import cfg from armada.cli import CliAction -from armada import const from armada.handlers.lock import lock_and_thread -from armada.handlers.manifest import Manifest +from armada.handlers.manifest import ManifestHelper from armada.handlers.test import Test from armada.handlers.tiller import Tiller from armada.utils.release import release_prefixer @@ -144,29 +143,25 @@ class TestChartManifest(CliAction): if self.file: if not self.ctx.obj.get('api', False): documents = list(yaml.safe_load_all(open(self.file).read())) - armada_obj = Manifest( - documents, - target_manifest=self.target_manifest).get_manifest() - prefix = armada_obj.get(const.KEYWORD_DATA).get( - const.KEYWORD_PREFIX) + manifest_helper = ManifestHelper( + documents, target_manifest=self.target_manifest) - for group in armada_obj.get(const.KEYWORD_DATA).get( - const.KEYWORD_GROUPS): - for ch in group.get(const.KEYWORD_CHARTS): - chart = ch['chart'] + release_prefix = manifest_helper.get_release_prefix() + for chart in manifest_helper.get_charts(): + release_name = release_prefixer(release_prefix, + chart.get('release')) - release_name = release_prefixer( - prefix, chart.get('release')) - if release_name in known_release_names: - test_handler = Test( - chart, - release_name, - tiller, - cleanup=self.cleanup, - enable_all=self.enable_all) + # Test if release is deployed + if release_name in known_release_names: + test_handler = Test( + chart, + release_name, + tiller, + cleanup=self.cleanup, + enable_all=self.enable_all) - if test_handler.test_enabled: - test_handler.test_release_for_success() + if test_handler.test_enabled: + test_handler.test_release_for_success() else: self.logger.info('Release %s not found - SKIPPING', release_name) diff --git a/armada/handlers/armada.py b/armada/handlers/armada.py index b2e567e6..77664d06 100644 --- a/armada/handlers/armada.py +++ b/armada/handlers/armada.py @@ -24,7 +24,7 @@ from armada.exceptions import source_exceptions from armada.exceptions import tiller_exceptions from armada.exceptions import validate_exceptions from armada.handlers.chart_deploy import ChartDeploy -from armada.handlers.manifest import Manifest +from armada.handlers.manifest import ManifestHelper from armada.handlers.override import Override from armada.utils.release import release_prefixer from armada.utils import source @@ -86,8 +86,9 @@ class Armada(object): except (validate_exceptions.InvalidManifestException, override_exceptions.InvalidOverrideValueException): raise - self.manifest = Manifest( - self.documents, target_manifest=target_manifest).get_manifest() + self.manifest_helper = ManifestHelper( + self.documents, target_manifest=target_manifest) + self.manifest = self.manifest_helper.get_manifest() self.chart_cache = {} self.chart_deploy = ChartDeploy( disable_update_pre, disable_update_post, self.dry_run, @@ -104,14 +105,11 @@ class Armada(object): raise tiller_exceptions.TillerServicesUnavailableException() # Clone the chart sources - manifest_data = self.manifest.get(const.KEYWORD_DATA, {}) - for group in manifest_data.get(const.KEYWORD_GROUPS, []): - for ch in group.get(const.KEYWORD_DATA).get( - const.KEYWORD_CHARTS, []): - self.get_chart(ch) + for chart in self.manifest_helper.get_chart_documents(): + self.get_chart(chart) - def get_chart(self, ch): - chart = ch.get(const.KEYWORD_DATA) + def get_chart(self, chart_document): + chart = chart_document.get(const.KEYWORD_DATA) chart_source = chart.get('source', {}) location = chart_source.get('location') ct_type = chart_source.get('type') @@ -159,10 +157,10 @@ class Armada(object): self.chart_cache[source_key] = repo_dir chart['source_dir'] = (self.chart_cache.get(source_key), subpath) else: - name = chart['metadata']['name'] + name = chart_document['metadata']['name'] raise source_exceptions.ChartSourceException(ct_type, name) - for dep in ch.get(const.KEYWORD_DATA, {}).get('dependencies', []): + for dep in chart.get('dependencies', []): self.get_chart(dep) def sync(self): @@ -186,12 +184,11 @@ class Armada(object): known_releases = self.tiller.list_releases() - manifest_data = self.manifest.get(const.KEYWORD_DATA, {}) - prefix = manifest_data.get(const.KEYWORD_PREFIX) + prefix = self.manifest_helper.get_release_prefix() - for cg in manifest_data.get(const.KEYWORD_GROUPS, []): - chartgroup = cg.get(const.KEYWORD_DATA) - cg_name = cg.get('metadata').get('name') + for doc in self.manifest_helper.get_chart_group_documents(): + chartgroup = doc.get(const.KEYWORD_DATA) + cg_name = doc.get('metadata').get('name') cg_desc = chartgroup.get('description', '') cg_sequenced = chartgroup.get('sequenced', False) or self.force_wait @@ -259,9 +256,8 @@ class Armada(object): self.post_flight_ops() if self.enable_chart_cleanup: - self._chart_cleanup( - prefix, - self.manifest[const.KEYWORD_DATA][const.KEYWORD_GROUPS], msg) + chart_groups = self.manifest_helper.get_chart_group_documents() + self._chart_cleanup(prefix, chart_groups, msg) LOG.info('Done applying manifest.') return msg diff --git a/armada/handlers/manifest.py b/armada/handlers/manifest.py index df6d4f7e..f41ec44b 100644 --- a/armada/handlers/manifest.py +++ b/armada/handlers/manifest.py @@ -136,7 +136,7 @@ class Manifest(object): details='Could not find {} named "{}"'.format( schema.TYPE_CHARTGROUP, name)) - def build_chart_deps(self, chart): + def _build_chart_deps(self, chart): """Recursively build chart dependencies for ``chart``. :param dict chart: The chart whose dependencies will be recursively @@ -153,7 +153,7 @@ class Manifest(object): if isinstance(dep, dict): continue chart_dep = self.find_chart_document(dep) - self.build_chart_deps(chart_dep) + self._build_chart_deps(chart_dep) chart[const.KEYWORD_DATA]['dependencies'][iter] = chart_dep except Exception: raise exceptions.ChartDependencyException( @@ -163,7 +163,7 @@ class Manifest(object): else: return chart - def build_chart_group(self, chart_group): + def _build_chart_group(self, chart_group): """Builds the chart dependencies for`charts`chart group``. :param dict chart_group: The chart_group whose dependencies @@ -181,7 +181,7 @@ class Manifest(object): if isinstance(chart, dict): continue chart_object = self.find_chart_document(chart) - self.build_chart_deps(chart_object) + self._build_chart_deps(chart_object) chart_group[const.KEYWORD_DATA][const.KEYWORD_CHARTS][iter] = \ chart_object except exceptions.ManifestException: @@ -192,7 +192,7 @@ class Manifest(object): return chart_group - def build_armada_manifest(self): + def _build_armada_manifest(self): """Builds the Armada manifest while pulling out data from the chart_group. @@ -207,7 +207,7 @@ class Manifest(object): if isinstance(group, dict): continue chart_grp = self.find_chart_group_document(group) - self.build_chart_group(chart_grp) + self._build_chart_group(chart_grp) self.manifest[const.KEYWORD_DATA][const.KEYWORD_GROUPS][iter] = \ chart_grp @@ -220,6 +220,73 @@ class Manifest(object): :returns: The Armada manifest. :rtype: dict """ - self.build_armada_manifest() + self._build_armada_manifest() return self.manifest + + +class ManifestHelper(Manifest): + + def __init__(self, documents, target_manifest=None): + super(ManifestHelper, self).__init__(documents, target_manifest) + + def get_chart_group_documents(self): + """Retrieve a list of documents corresponding to the chart groups + listed in the selected/targeted manifest (self.manifest). + + A chart group document contains a metadata and data section. + + :returns: List of chart group documents + :rtype: list + """ + return self.get_manifest().get(const.KEYWORD_DATA).get( + const.KEYWORD_GROUPS) + + def get_chart_groups(self): + """Retrieve a list of chart group dictionaries corresponding to the + chart groups listed in the selected/targeted manifest (self.manifest). + + A chart group dictionary is the data section of a chart group document. + + :returns: List of chart groups dictionaries + :rtype: list + """ + group_names = self.get_chart_group_documents() + return [group.get(const.KEYWORD_DATA) for group in group_names] + + def get_chart_documents(self): + """Retrieve a list of documents corresponding to the charts listed in + all chart groups listed in the selected/targeted manifest + (self.manifest). + + A chart document contains a metadata and data section. + + :returns: List of chart documents + :rtype: list + """ + charts = list() + for group in self.get_chart_groups(): + charts.extend(group.get(const.KEYWORD_CHARTS)) + + return charts + + def get_charts(self): + """Retrieve a list of chart dictionaries corresponding to the charts + listed in all chart groups listed in the selected/targeted manifest. + + A chart dictionary is the data section of a chart document. + + :returns: List of charts that belong to the manifest. + :rtype: list + """ + chart_documents = self.get_chart_documents() + return [chart.get(const.KEYWORD_DATA) for chart in chart_documents] + + def get_release_prefix(self): + """Retrieve the release prefix of the selected/targeted manifest. + + :returns: Release prefix + :rtype: str + """ + manifest_data = self.get_manifest().get(const.KEYWORD_DATA) + return manifest_data.get(const.KEYWORD_PREFIX) diff --git a/armada/tests/unit/api/test_test_controller.py b/armada/tests/unit/api/test_test_controller.py index 335de7cb..d1a31ba5 100644 --- a/armada/tests/unit/api/test_test_controller.py +++ b/armada/tests/unit/api/test_test_controller.py @@ -30,7 +30,7 @@ from armada.tests.unit.api import base test.TestReleasesManifestController.handle.__wrapped__) class TestReleasesManifestControllerTest(base.BaseControllerTest): - @mock.patch.object(test, 'Manifest') + @mock.patch.object(test, 'ManifestHelper') @mock.patch.object(api, 'Tiller') def test_test_controller_with_manifest(self, mock_tiller, mock_manifest): rules = {'armada:test_manifest': '@'} @@ -127,7 +127,7 @@ class TestReleasesReleaseNameControllerTest(base.BaseControllerTest): test.TestReleasesManifestController.handle.__wrapped__) class TestReleasesManifestControllerNegativeTest(base.BaseControllerTest): - @mock.patch.object(test, 'Manifest') + @mock.patch.object(test, 'ManifestHelper') @mock.patch.object(api, 'Tiller') @mock.patch.object(test.Test, 'test_release_for_success') def test_test_controller_tiller_exc_returns_500( @@ -141,7 +141,7 @@ class TestReleasesManifestControllerNegativeTest(base.BaseControllerTest): resp = self.app.simulate_post('/api/v1.0/tests') self.assertEqual(500, resp.status_code) - @mock.patch.object(test, 'Manifest') + @mock.patch.object(test, 'ManifestHelper') @mock.patch.object(api, 'Tiller') def test_test_controller_validation_failure_returns_400( self, mock_tiller, mock_manifest): diff --git a/armada/tests/unit/handlers/test_armada.py b/armada/tests/unit/handlers/test_armada.py index 1a280690..1e150faf 100644 --- a/armada/tests/unit/handlers/test_armada.py +++ b/armada/tests/unit/handlers/test_armada.py @@ -341,14 +341,11 @@ class ArmadaHandlerTestCase(base.ArmadaTestCase): self._test_pre_flight_ops(armada_obj) armada_obj.post_flight_ops() - - for group in armada_obj.manifest['data']['chart_groups']: - for counter, chart in enumerate( - group.get(const.KEYWORD_DATA).get(const.KEYWORD_CHARTS)): - if chart.get( - const.KEYWORD_DATA).get('source').get('type') == 'git': - mock_source.source_cleanup.assert_called_with( - CHART_SOURCES[counter][0]) + charts = armada_obj.manifest_helper.get_charts() + for counter, chart in enumerate(charts): + if chart.get('source').get('type') == 'git': + mock_source.source_cleanup.assert_called_with( + CHART_SOURCES[counter][0]) # TODO(seaneagan): Separate ChartDeploy tests into separate module. # TODO(seaneagan): Once able to make mock library sufficiently thread safe, @@ -378,8 +375,8 @@ class ArmadaHandlerTestCase(base.ArmadaTestCase): armada_obj = armada.Armada(yaml_documents, m_tiller) armada_obj.chart_deploy.get_diff = mock.Mock() - cg = armada_obj.manifest['data']['chart_groups'][0] - chart_group = cg['data'] + cg = armada_obj.manifest_helper.get_chart_group_documents()[0] + chart_group = cg.get('data') charts = chart_group['chart_group'] cg_test_all_charts = chart_group.get('test_charts') diff --git a/armada/tests/unit/handlers/test_manifest.py b/armada/tests/unit/handlers/test_manifest.py index be65ab72..c94979bb 100644 --- a/armada/tests/unit/handlers/test_manifest.py +++ b/armada/tests/unit/handlers/test_manifest.py @@ -23,6 +23,71 @@ from armada.handlers import manifest from armada.handlers import schema from armada.utils import validate +MANIFEST = """ +--- +schema: armada/Manifest/v1 +metadata: + schema: metadata/Document/v1 + name: example-manifest +data: + release_prefix: armada + chart_groups: + - example-group +--- + +schema: armada/ChartGroup/v1 +metadata: + schema: metadata/Document/v1 + name: example-group +data: + description: this is a test + sequenced: True + chart_group: + - example-chart-1 + - example-chart-2 +--- +schema: armada/Chart/v1 +metadata: + schema: metadata/Document/v1 + name: example-chart-1 +data: + chart_name: example-chart-1 + release: example-chart-1 + namespace: test + values: {} + source: + type: local + location: /tmp/dummy/armada + subpath: chart_1 + dependencies: [] + test: true + wait: + timeout: 10 + upgrade: + no_hooks: false +--- +schema: armada/Chart/v1 +metadata: + schema: metadata/Document/v1 + name: example-chart-2 +data: + chart_name: example-chart-2 + release: example-chart-2 + namespace: test + values: {} + source: + type: local + location: /tmp/dummy/armada + subpath: chart_2 + dependencies: [] + protected: + continue_processing: false + wait: + timeout: 10 + upgrade: + no_hooks: false +""" + class ManifestTestCase(testtools.TestCase): @@ -183,10 +248,10 @@ class ManifestTestCase(testtools.TestCase): self.assertIsInstance(kis_chart, dict) self.assertEqual(self.documents[-4], kis_chart) - def test_verify_build_armada_manifest(self): + def test_verify__build_armada_manifest(self): armada_manifest = manifest.Manifest(self.documents) - built_armada_manifest = armada_manifest.build_armada_manifest() + built_armada_manifest = armada_manifest._build_armada_manifest() self.assertIsNotNone(built_armada_manifest) self.assertIsInstance(built_armada_manifest, dict) @@ -205,20 +270,20 @@ class ManifestTestCase(testtools.TestCase): self.assertEqual(openstack_keystone_chart_group, built_armada_manifest['data']['chart_groups'][1]) - def test_verify_build_chart_group_deps(self): + 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) + _build_chart_group(chart_group) openstack_keystone_chart_group_deps_dep_added = \ openstack_keystone_chart_group_deps[ 'data']['chart_group'][0]['data']['dependencies'] # keystone chart dependencies keystone_chart = armada_manifest.find_chart_document('keystone') - keystone_chart_with_deps = armada_manifest.build_chart_deps( + keystone_chart_with_deps = armada_manifest._build_chart_deps( keystone_chart) keystone_dependencies = keystone_chart_with_deps['data'][ 'dependencies'] @@ -230,20 +295,20 @@ class ManifestTestCase(testtools.TestCase): chart_group = armada_manifest.find_chart_group_document( 'keystone-infra-services') openstack_keystone_chart_group_deps = armada_manifest. \ - build_chart_group(chart_group) + _build_chart_group(chart_group) keystone_infra_services_dep_added = \ openstack_keystone_chart_group_deps[ 'data']['chart_group'][0]['data']['dependencies'] # building mariadb chart dependencies mariadb_chart = armada_manifest.find_chart_document('mariadb') - mariadb_chart_with_deps = armada_manifest.build_chart_deps( + 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_with_deps = armada_manifest._build_chart_deps( memcached_chart) memcached_dependencies = memcached_chart_with_deps['data'][ 'dependencies'] @@ -253,14 +318,14 @@ class ManifestTestCase(testtools.TestCase): self.assertEqual(keystone_infra_services_dep_added[0], memcached_dependencies[0]) - def test_verify_build_chart_deps(self): + 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_with_deps = armada_manifest._build_chart_deps( helm_toolkit_chart).get('data') # since not dependent on other charts, the original and modified @@ -275,7 +340,7 @@ class ManifestTestCase(testtools.TestCase): # 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_with_deps = armada_manifest._build_chart_deps( keystone_chart) self.assertNotEqual(original_keystone_chart, keystone_chart_with_deps) @@ -293,7 +358,7 @@ class ManifestTestCase(testtools.TestCase): # 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_with_deps = armada_manifest._build_chart_deps( mariadb_chart) self.assertNotEqual(original_mariadb_chart, mariadb_chart_with_deps) @@ -310,7 +375,7 @@ class ManifestTestCase(testtools.TestCase): # 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_with_deps = armada_manifest._build_chart_deps( memcached_chart) self.assertNotEqual(original_memcached_chart, @@ -397,7 +462,7 @@ class ManifestNegativeTestCase(testtools.TestCase): armada_manifest.find_chart_group_document, 'invalid') - def test_build_chart_deps_with_missing_dependency_fails(self): + def test__build_chart_deps_with_missing_dependency_fails(self): """Validate that attempting to build a chart that points to a missing dependency fails. """ @@ -405,7 +470,7 @@ class ManifestNegativeTestCase(testtools.TestCase): valid, details = validate.validate_armada_documents(self.documents) self.assertFalse(valid) - def test_build_chart_group_with_missing_chart_grp_fails(self): + def test__build_chart_group_with_missing_chart_grp_fails(self): """Validate that attempting to build a chart group document with missing chart group fails. """ @@ -413,10 +478,55 @@ class ManifestNegativeTestCase(testtools.TestCase): valid, details = validate.validate_armada_documents(self.documents) self.assertFalse(valid) - def test_build_armada_manifest_with_missing_chart_grps_fails(self): + def test__build_armada_manifest_with_missing_chart_grps_fails(self): """Validate that attempting to build a manifest with missing chart groups fails. """ self.documents[6]['data']['chart_groups'] = ['missing-chart-groups'] valid, details = validate.validate_armada_documents(self.documents) self.assertFalse(valid) + + +class ManifestHelperTestCase(testtools.TestCase): + + def setUp(self): + super(ManifestHelperTestCase, self).setUp() + + docs = list(yaml.safe_load_all(MANIFEST)) + self.manifest_helper = manifest.ManifestHelper(docs) + + def test_get_chart_group_documents(self): + chart_group_docs = self.manifest_helper.get_chart_group_documents() + self.assertIsInstance(chart_group_docs, list) + + for doc in chart_group_docs: + metadata = doc.get('metadata', None) + data = doc.get('data', None) + + self.assertIsInstance(metadata, dict) + self.assertIsInstance(data, dict) + + def test_get_chart_groups_documents(self): + chart_groups = self.manifest_helper.get_chart_documents() + self.assertIsInstance(chart_groups, list) + + for doc in chart_groups: + metadata = doc.get('metadata', None) + data = doc.get('data', None) + + self.assertIsInstance(metadata, dict) + self.assertIsInstance(data, dict) + + def test_get_charts(self): + charts = self.manifest_helper.get_charts() + self.assertIsInstance(charts, list) + + for chart in charts: + self.assertIsInstance(chart, dict) + + def test_get_chart_groups(self): + chart_groups = self.manifest_helper.get_chart_groups() + self.assertIsInstance(chart_groups, list) + + for chart_group in chart_groups: + self.assertIsInstance(chart_group, dict)