diff --git a/blueprints/data-solutions/data-platform-foundations/README.md b/blueprints/data-solutions/data-platform-foundations/README.md index d014e2f6..76810f54 100644 --- a/blueprints/data-solutions/data-platform-foundations/README.md +++ b/blueprints/data-solutions/data-platform-foundations/README.md @@ -222,7 +222,7 @@ module "data-platform" { prefix = "myprefix" } -# tftest modules=1 resources=1 +# tftest modules=42 resources=314 ``` ## Customizations diff --git a/blueprints/gke/multitenant-fleet/README.md b/blueprints/gke/multitenant-fleet/README.md index 68909b82..841971a0 100644 --- a/blueprints/gke/multitenant-fleet/README.md +++ b/blueprints/gke/multitenant-fleet/README.md @@ -95,7 +95,7 @@ module "gke" { } } } -# tftest modules=1 resources=0 +# tftest modules=5 resources=26 ``` ## Creating Multiple Clusters @@ -185,7 +185,7 @@ module "gke" { } } } -# tftest modules=1 resources=0 +# tftest modules=7 resources=28 ``` ## Multiple clusters with GKE Fleet @@ -305,7 +305,7 @@ module "gke" { } } -# tftest modules=1 resources=0 +# tftest modules=8 resources=39 ``` diff --git a/modules/compute-vm/README.md b/modules/compute-vm/README.md index c700ddfa..19609682 100644 --- a/modules/compute-vm/README.md +++ b/modules/compute-vm/README.md @@ -247,7 +247,7 @@ module "vm-with-gvnic" { } service_account_create = true } -# tftest modules=1 resources=2 +# tftest modules=1 resources=3 ``` ### Instance template diff --git a/modules/net-glb/README.md b/modules/net-glb/README.md index cb561d42..635f29f0 100644 --- a/modules/net-glb/README.md +++ b/modules/net-glb/README.md @@ -154,7 +154,7 @@ resource "google_compute_region_network_endpoint_group" "serverless-neg" { service = "my-cloud-run-service" } } -# tftest modules=1 resources=4 +# tftest modules=1 resources=5 ``` ### Mixing Backends @@ -478,7 +478,7 @@ resource "tls_self_signed_cert" "self_signed_cert" { organization = "My Test Org" } } -# tftest modules=1 resources=6 +# tftest modules=1 resources=8 ``` ## Regional Load Balancing diff --git a/modules/net-ilb-l7/README.md b/modules/net-ilb-l7/README.md index 20bced5c..5dabc52d 100644 --- a/modules/net-ilb-l7/README.md +++ b/modules/net-ilb-l7/README.md @@ -158,7 +158,7 @@ resource "google_compute_network_endpoint_group" "my-neg" { default_port = "90" zone = "europe-west1-b" } -# tftest modules=1 resources=5 +# tftest modules=1 resources=6 ``` --> @@ -367,7 +367,7 @@ resource "tls_self_signed_cert" "self_signed_cert" { organization = "My Test Org" } } -# tftest modules=1 resources=6 +# tftest modules=1 resources=8 ``` ## Components And Files Mapping diff --git a/tests/conftest.py b/tests/conftest.py index f6c0069b..d32e2fad 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -88,18 +88,28 @@ def e2e_plan_runner(_plan_runner): @pytest.fixture(scope='session') -def doc_example_plan_runner(_plan_runner): - "Returns a function to run Terraform plan on documentation examples." +def recursive_e2e_plan_runner(_plan_runner): + """Plan runner for end-to-end root module, returns total number of + (nested) modules and resources""" - def run_plan(fixture_path=None): - "Runs Terraform plan and returns count of modules and resources." - tf = tftest.TerraformTest(fixture_path, BASEDIR, - os.environ.get('TERRAFORM', 'terraform')) - tf.setup(upgrade=True) - plan = tf.plan(output=True, refresh=True) - # the fixture is the example we are testing - modules = plan.modules or {} - return (len(modules), sum(len(m.resources) for m in modules.values())) + def walk_plan(node, modules, resources): + # TODO(jccb): this would be better with node.get() but + # TerraformPlanOutput objects don't have it + new_modules = node['child_modules'] if 'child_modules' in node else [] + resources += node['resources'] if 'resources' in node else [] + modules += new_modules + for module in new_modules: + walk_plan(module, modules, resources) + + def run_plan(fixture_path=None, targets=None, refresh=True, + include_bare_resources=False, compute_sums=True, **tf_vars): + "Runs Terraform plan on a root module using defaults, returns data." + plan = _plan_runner(fixture_path, targets=targets, refresh=refresh, + **tf_vars) + modules = [] + resources = [] + walk_plan(plan.root_module, modules, resources) + return len(modules), len(resources) return run_plan diff --git a/tests/examples/test_plan.py b/tests/examples/test_plan.py index 23a68eea..f82e7ccf 100644 --- a/tests/examples/test_plan.py +++ b/tests/examples/test_plan.py @@ -19,7 +19,7 @@ BASE_PATH = Path(__file__).parent EXPECTED_RESOURCES_RE = re.compile(r'# tftest modules=(\d+) resources=(\d+)') -def test_example(doc_example_plan_runner, tmp_path, example): +def test_example(recursive_e2e_plan_runner, tmp_path, example): (tmp_path / 'fabric').symlink_to(Path(BASE_PATH, '../../').resolve()) (tmp_path / 'variables.tf').symlink_to( Path(BASE_PATH, 'variables.tf').resolve()) @@ -29,6 +29,6 @@ def test_example(doc_example_plan_runner, tmp_path, example): expected_modules = int(match.group(1)) if match is not None else 1 expected_resources = int(match.group(2)) if match is not None else 1 - num_modules, num_resources = doc_example_plan_runner(str(tmp_path)) + num_modules, num_resources = recursive_e2e_plan_runner(str(tmp_path)) assert expected_modules == num_modules assert expected_resources == num_resources diff --git a/tests/fast/conftest.py b/tests/fast/conftest.py deleted file mode 100644 index 976637eb..00000000 --- a/tests/fast/conftest.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright 2022 Google LLC -# -# 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. -"Shared fixtures" - -import inspect -import os -import types - -import pytest -import tftest - -BASEDIR = os.path.dirname(os.path.dirname(__file__)) - - -@pytest.fixture(scope='session') -def fast_e2e_plan_runner(_plan_runner): - "Plan runner for end-to-end root module, returns modules and resources." - - def run_plan(fixture_path=None, targets=None, refresh=True, - include_bare_resources=False, compute_sums=True, **tf_vars): - "Runs Terraform plan on a root module using defaults, returns data." - plan = _plan_runner(fixture_path, targets=targets, refresh=refresh, - **tf_vars) - root_module = plan.root_module['child_modules'][0] - - # Count all modules and resources up to 2 levels deep. We include - # the second level to account for wrapper modules used by stages 3 - modules = {} - for m in root_module['child_modules']: - key = m['address'].removeprefix(root_module['address'])[1:] - modules[key] = m.get('resources', []) - if m.get('child_modules'): - for m2 in m['child_modules']: - key2 = m2['address'].removeprefix(root_module['address'])[1:] - modules[key2] = m2.get('resources', []) - - resources = [r for m in modules.values() for r in m] - if include_bare_resources: - bare_resources = root_module['resources'] - resources.extend(bare_resources) - if compute_sums: - return len(modules), len(resources), { - k: len(v) for k, v in modules.items() - } - return modules, resources - - return run_plan diff --git a/tests/fast/stages/s00_bootstrap/test_plan.py b/tests/fast/stages/s00_bootstrap/test_plan.py index 2201cfcc..78146970 100644 --- a/tests/fast/stages/s00_bootstrap/test_plan.py +++ b/tests/fast/stages/s00_bootstrap/test_plan.py @@ -26,8 +26,8 @@ # } -def test_counts(fast_e2e_plan_runner): +def test_counts(recursive_e2e_plan_runner): "Test stage." # TODO: to re-enable per-module resource count check print _, then test - num_modules, num_resources, _ = fast_e2e_plan_runner() + num_modules, num_resources = recursive_e2e_plan_runner() assert num_modules > 0 and num_resources > 0 diff --git a/tests/fast/stages/s01_resman/test_plan.py b/tests/fast/stages/s01_resman/test_plan.py index 6189f62e..5f105806 100644 --- a/tests/fast/stages/s01_resman/test_plan.py +++ b/tests/fast/stages/s01_resman/test_plan.py @@ -13,8 +13,8 @@ # limitations under the License. -def test_counts(fast_e2e_plan_runner): +def test_counts(recursive_e2e_plan_runner): "Test stage." - num_modules, num_resources, _ = fast_e2e_plan_runner() + num_modules, num_resources = recursive_e2e_plan_runner() # TODO: to re-enable per-module resource count check print _, then test assert num_modules > 0 and num_resources > 0 diff --git a/tests/fast/stages/s02_networking_nva/test_plan.py b/tests/fast/stages/s02_networking_nva/test_plan.py index 6189f62e..5f105806 100644 --- a/tests/fast/stages/s02_networking_nva/test_plan.py +++ b/tests/fast/stages/s02_networking_nva/test_plan.py @@ -13,8 +13,8 @@ # limitations under the License. -def test_counts(fast_e2e_plan_runner): +def test_counts(recursive_e2e_plan_runner): "Test stage." - num_modules, num_resources, _ = fast_e2e_plan_runner() + num_modules, num_resources = recursive_e2e_plan_runner() # TODO: to re-enable per-module resource count check print _, then test assert num_modules > 0 and num_resources > 0 diff --git a/tests/fast/stages/s02_networking_peering/test_plan.py b/tests/fast/stages/s02_networking_peering/test_plan.py index b4de02f9..917c90c1 100644 --- a/tests/fast/stages/s02_networking_peering/test_plan.py +++ b/tests/fast/stages/s02_networking_peering/test_plan.py @@ -27,9 +27,9 @@ STAGE_PEERING = STAGES / '02-networking-peering' STAGE_VPN = STAGES / '02-networking-vpn' -def test_counts(fast_e2e_plan_runner): +def test_counts(recursive_e2e_plan_runner): 'Test stage.' - num_modules, num_resources, _ = fast_e2e_plan_runner() + num_modules, num_resources = recursive_e2e_plan_runner() # TODO: to re-enable per-module resource count check print _, then test assert num_modules > 0 and num_resources > 0 diff --git a/tests/fast/stages/s02_networking_vpn/test_plan.py b/tests/fast/stages/s02_networking_vpn/test_plan.py index 6189f62e..5f105806 100644 --- a/tests/fast/stages/s02_networking_vpn/test_plan.py +++ b/tests/fast/stages/s02_networking_vpn/test_plan.py @@ -13,8 +13,8 @@ # limitations under the License. -def test_counts(fast_e2e_plan_runner): +def test_counts(recursive_e2e_plan_runner): "Test stage." - num_modules, num_resources, _ = fast_e2e_plan_runner() + num_modules, num_resources = recursive_e2e_plan_runner() # TODO: to re-enable per-module resource count check print _, then test assert num_modules > 0 and num_resources > 0 diff --git a/tests/fast/stages/s02_security/test_plan.py b/tests/fast/stages/s02_security/test_plan.py index 6189f62e..5f105806 100644 --- a/tests/fast/stages/s02_security/test_plan.py +++ b/tests/fast/stages/s02_security/test_plan.py @@ -13,8 +13,8 @@ # limitations under the License. -def test_counts(fast_e2e_plan_runner): +def test_counts(recursive_e2e_plan_runner): "Test stage." - num_modules, num_resources, _ = fast_e2e_plan_runner() + num_modules, num_resources = recursive_e2e_plan_runner() # TODO: to re-enable per-module resource count check print _, then test assert num_modules > 0 and num_resources > 0 diff --git a/tests/fast/stages/s03_data_platform/test_plan.py b/tests/fast/stages/s03_data_platform/test_plan.py index 6189f62e..5f105806 100644 --- a/tests/fast/stages/s03_data_platform/test_plan.py +++ b/tests/fast/stages/s03_data_platform/test_plan.py @@ -13,8 +13,8 @@ # limitations under the License. -def test_counts(fast_e2e_plan_runner): +def test_counts(recursive_e2e_plan_runner): "Test stage." - num_modules, num_resources, _ = fast_e2e_plan_runner() + num_modules, num_resources = recursive_e2e_plan_runner() # TODO: to re-enable per-module resource count check print _, then test assert num_modules > 0 and num_resources > 0 diff --git a/tests/fast/stages/s03_gke_multitenant/test_plan.py b/tests/fast/stages/s03_gke_multitenant/test_plan.py index 6189f62e..5f105806 100644 --- a/tests/fast/stages/s03_gke_multitenant/test_plan.py +++ b/tests/fast/stages/s03_gke_multitenant/test_plan.py @@ -13,8 +13,8 @@ # limitations under the License. -def test_counts(fast_e2e_plan_runner): +def test_counts(recursive_e2e_plan_runner): "Test stage." - num_modules, num_resources, _ = fast_e2e_plan_runner() + num_modules, num_resources = recursive_e2e_plan_runner() # TODO: to re-enable per-module resource count check print _, then test assert num_modules > 0 and num_resources > 0 diff --git a/tests/fast/stages/s03_project_factory/test_plan.py b/tests/fast/stages/s03_project_factory/test_plan.py index 6189f62e..5f105806 100644 --- a/tests/fast/stages/s03_project_factory/test_plan.py +++ b/tests/fast/stages/s03_project_factory/test_plan.py @@ -13,8 +13,8 @@ # limitations under the License. -def test_counts(fast_e2e_plan_runner): +def test_counts(recursive_e2e_plan_runner): "Test stage." - num_modules, num_resources, _ = fast_e2e_plan_runner() + num_modules, num_resources = recursive_e2e_plan_runner() # TODO: to re-enable per-module resource count check print _, then test assert num_modules > 0 and num_resources > 0