Example #1
0
    def test_env_file(self, tmp_path):
        """Test that the correct env file is selected."""
        test_env = tmp_path / 'test.env'
        # python2 Path.write_text requires unicode
        test_env.write_text(u'test_value: test')

        # support python < 3.6
        result = CFNgin(ctx=self.get_context(), sys_path=str(tmp_path))
        assert result.env_file.test_value == 'test'

        test_us_east_1 = tmp_path / 'test-us-east-1.env'
        # python2 Path.write_text requires unicode
        test_us_east_1.write_text(u'test_value: test-us-east-1')

        test_us_west_2 = tmp_path / 'test-us-west-2.env'
        # python2 Path.write_text requires unicode
        test_us_west_2.write_text(u'test_value: test-us-west-2')

        lab_ca_central_1 = tmp_path / 'lab-ca-central-1.env'
        # python2 Path.write_text requires unicode
        lab_ca_central_1.write_text(u'test_value: lab-ca-central-1')

        # support python < 3.6
        result = CFNgin(ctx=self.get_context(), sys_path=str(tmp_path))
        assert result.env_file.test_value == 'test-us-east-1'

        result = CFNgin(ctx=self.get_context(region='us-west-2'),
                        sys_path=str(tmp_path))  # support python < 3.6
        assert result.env_file.test_value == 'test-us-west-2'

        result = CFNgin(ctx=self.get_context(name='lab',
                                             region='ca-central-1'),
                        sys_path=str(tmp_path))  # support python < 3.6
        assert result.env_file.test_value == 'lab-ca-central-1'
Example #2
0
    def test_deploy(self, mock_action, cfngin_fixtures, tmp_path):
        """Test deploy with two files & class init."""
        mock_instance = self.configure_mock_action_instance(mock_action)
        copy_basic_fixtures(cfngin_fixtures, tmp_path)
        copy_fixture(src=cfngin_fixtures / 'configs' / 'basic.yml',
                     dest=tmp_path / 'basic2.yml')

        context = self.get_context()
        context.env_vars['CI'] = '1'

        cfngin = CFNgin(ctx=context,
                        parameters={'test_param': 'test-param-value'},
                        sys_path=str(tmp_path))  # support python < 3.6
        cfngin.deploy()

        assert cfngin.concurrency == 0
        assert not cfngin.interactive
        assert cfngin.parameters.bucket_name == 'cfngin-bucket'
        assert cfngin.parameters.environment == 'test'
        assert cfngin.parameters.namespace == 'test-namespace'
        assert cfngin.parameters.region == 'us-east-1'
        assert cfngin.parameters.test_key == 'test_value'
        assert cfngin.parameters.test_param == 'test-param-value'
        assert cfngin.recreate_failed
        assert cfngin.region == 'us-east-1'
        assert cfngin.sys_path == str(tmp_path)
        assert not cfngin.tail

        assert mock_action.call_count == 2
        mock_instance.execute.has_calls([{'concurrency': 0,
                                          'tail': False},
                                         {'concurrency': 0,
                                          'tail': False}])
Example #3
0
    def test_find_config_files(self, tmp_path):
        """Test find_config_files."""
        bad_path = tmp_path / 'bad_path'
        bad_path.mkdir()
        # tmp_path.stem

        good_config_paths = [
            tmp_path / '_t3sT.yaml', tmp_path / '_t3sT.yml',
            tmp_path / '01-config.yaml', tmp_path / '01-config.yml',
            tmp_path / 'TeSt_02.yaml', tmp_path / 'TeSt_02.yml',
            tmp_path / 'test.config.yaml', tmp_path / 'test.config.yml'
        ]
        bad_config_paths = [
            tmp_path / '.anything.yaml', tmp_path / '.gitlab-ci.yml',
            tmp_path / 'docker-compose.yml', bad_path / '00-invalid.yml'
        ]

        for config_path in good_config_paths + bad_config_paths:
            # python2 Path.write_text requires unicode
            config_path.write_text(u'')

        # support python < 3.6
        result = CFNgin.find_config_files(sys_path=str(tmp_path))
        expected = sorted(
            [str(config_path) for config_path in good_config_paths])
        assert result == expected

        config_01 = tmp_path / '01-config.yml'
        result = CFNgin.find_config_files(
            sys_path=str(config_01)  # support python < 3.6
        )
        assert result == [str(config_01)]  # support python < 3.6

        result = CFNgin.find_config_files()
        assert not result
Example #4
0
    def test_deploy(self, mock_action, cfngin_fixtures, tmp_path, patch_safehaven):
        """Test deploy with two files & class init."""
        mock_instance = self.configure_mock_action_instance(mock_action)
        copy_basic_fixtures(cfngin_fixtures, tmp_path)
        copy_fixture(
            src=cfngin_fixtures / "configs" / "basic.yml", dest=tmp_path / "basic2.yml"
        )

        context = self.get_context()
        context.env_vars["CI"] = "1"

        cfngin = CFNgin(
            ctx=context,
            parameters={"test_param": "test-param-value"},
            sys_path=str(tmp_path),
        )  # support python < 3.6
        cfngin.deploy()

        assert cfngin.concurrency == 0
        assert not cfngin.interactive
        assert cfngin.parameters.bucket_name == "cfngin-bucket"
        assert cfngin.parameters.environment == "test"
        assert cfngin.parameters.namespace == "test-namespace"
        assert cfngin.parameters.region == "us-east-1"
        assert cfngin.parameters.test_key == "test_value"
        assert cfngin.parameters.test_param == "test-param-value"
        assert cfngin.recreate_failed
        assert cfngin.region == "us-east-1"
        assert cfngin.sys_path == str(tmp_path)
        assert not cfngin.tail

        assert mock_action.call_count == 2
        mock_instance.execute.has_calls(
            [{"concurrency": 0, "tail": False}, {"concurrency": 0, "tail": False}]
        )
        patch_safehaven.assert_has_calls(
            [
                call(
                    environ=context.env_vars,
                    sys_modules_exclude=["awacs", "troposphere"],
                ),
                call.__enter__(),
                call(
                    argv=["stacker", "build", str(tmp_path / "basic.yml")],
                    sys_modules_exclude=["awacs", "troposphere"],
                ),
                call.__enter__(),
                call.__exit__(None, None, None),
                call(
                    argv=["stacker", "build", str(tmp_path / "basic2.yml")],
                    sys_modules_exclude=["awacs", "troposphere"],
                ),
                call.__enter__(),
                call.__exit__(None, None, None),
                call.__exit__(None, None, None),
            ]
        )
Example #5
0
    def test_plan(self, mock_action, cfngin_fixtures, tmp_path):
        """Test plan."""
        mock_instance = self.configure_mock_action_instance(mock_action)
        copy_basic_fixtures(cfngin_fixtures, tmp_path)

        # support python < 3.6
        cfngin = CFNgin(ctx=self.get_context(), sys_path=str(tmp_path))
        cfngin.plan()

        mock_action.assert_called_once()
        mock_instance.execute.assert_called_once_with()
Example #6
0
    def test_load(self, cfngin_fixtures, tmp_path):
        """Test load."""
        copy_basic_fixtures(cfngin_fixtures, tmp_path)
        # support python < 3.6
        cfngin = CFNgin(ctx=self.get_context(), sys_path=str(tmp_path))
        result = cfngin.load(str(tmp_path / 'basic.yml'))  # support python < 3.6

        assert not result.bucket_name
        assert result.namespace == 'test-namespace'
        assert len(result.get_stacks()) == 1
        assert result.get_stacks()[0].name == 'test-stack'
Example #7
0
    def test_load_cfn_template(self, caplog, tmp_path):
        """Test load a CFN template."""
        cfn_template = tmp_path / 'template.yml'
        cfn_template.write_text(u'test_key: !Ref something')
        cfngin = CFNgin(ctx=self.get_context(), sys_path=str(tmp_path))

        caplog.set_level('ERROR', logger='runway.cfngin')

        with pytest.raises(SystemExit):
            cfngin.load(str(cfn_template))  # support python < 3.6

        assert 'appears to be a CloudFormation template' in caplog.text
Example #8
0
    def test_deploy(self, mock_action, cfngin_fixtures, tmp_path,
                    patch_safehaven):
        """Test deploy with two files & class init."""
        mock_instance = self.configure_mock_action_instance(mock_action)
        copy_basic_fixtures(cfngin_fixtures, tmp_path)
        copy_fixture(src=cfngin_fixtures / 'configs' / 'basic.yml',
                     dest=tmp_path / 'basic2.yml')

        context = self.get_context()
        context.env_vars['CI'] = '1'

        cfngin = CFNgin(ctx=context,
                        parameters={'test_param': 'test-param-value'},
                        sys_path=str(tmp_path))  # support python < 3.6
        cfngin.deploy()

        assert cfngin.concurrency == 0
        assert not cfngin.interactive
        assert cfngin.parameters.bucket_name == 'cfngin-bucket'
        assert cfngin.parameters.environment == 'test'
        assert cfngin.parameters.namespace == 'test-namespace'
        assert cfngin.parameters.region == 'us-east-1'
        assert cfngin.parameters.test_key == 'test_value'
        assert cfngin.parameters.test_param == 'test-param-value'
        assert cfngin.recreate_failed
        assert cfngin.region == 'us-east-1'
        assert cfngin.sys_path == str(tmp_path)
        assert not cfngin.tail

        assert mock_action.call_count == 2
        mock_instance.execute.has_calls([{
            'concurrency': 0,
            'tail': False
        }, {
            'concurrency': 0,
            'tail': False
        }])
        patch_safehaven.assert_has_calls([
            call(environ=context.env_vars,
                 sys_modules_exclude=['awacs', 'troposphere']),
            call.__enter__(),
            call(argv=['stacker', 'build',
                       str(tmp_path / 'basic.yml')],
                 sys_modules_exclude=['awacs', 'troposphere']),
            call.__enter__(),
            call.__exit__(None, None, None),
            call(argv=['stacker', 'build',
                       str(tmp_path / 'basic2.yml')],
                 sys_modules_exclude=['awacs', 'troposphere']),
            call.__enter__(),
            call.__exit__(None, None, None),
            call.__exit__(None, None, None),
        ])
Example #9
0
    def test_destroy(self, mock_action, cfngin_fixtures, tmp_path):
        """Test destroy."""
        mock_instance = self.configure_mock_action_instance(mock_action)
        copy_basic_fixtures(cfngin_fixtures, tmp_path)

        # support python < 3.6
        cfngin = CFNgin(ctx=self.get_context(), sys_path=str(tmp_path))
        cfngin.destroy()

        mock_action.assert_called_once()
        mock_instance.execute.assert_called_once_with(concurrency=0,
                                                      force=True,
                                                      tail=False)
Example #10
0
    def test_plan(self, mock_action, cfngin_fixtures, tmp_path):
        """Test plan."""
        mock_instance = self.configure_mock_action_instance(mock_action)
        copy_basic_fixtures(cfngin_fixtures, tmp_path)

        # support python < 3.6
        cfngin = CFNgin(ctx=self.get_context(), sys_path=str(tmp_path))
        cfngin.plan()

        assert get_env_creds() == cfngin._aws_credential_backup, \
            'env vars should be reverted upon completion'
        mock_action.assert_called_once()
        mock_instance.execute.assert_called_once_with()
Example #11
0
    def test_should_skip(self, cfngin_fixtures, tmp_path):
        """Test should_skip."""
        # support python < 3.6
        cfngin = CFNgin(ctx=self.get_context(), sys_path=str(tmp_path))
        del cfngin.env_file  # clear cached value and force load

        assert cfngin.should_skip()
        del cfngin.env_file  # clear cached value and force load
        assert not cfngin.should_skip(
            force=True)  # does not repopulate env_file

        copy_basic_fixtures(cfngin_fixtures, tmp_path)
        assert not cfngin.should_skip()
        del cfngin.env_file  # clear cached value and force load
        assert not cfngin.should_skip(
            force=True)  # does not repopulate env_file

        env_region_file = tmp_path / 'test-us-east-1.env'
        env_file = tmp_path / 'test.env'
        copy_fixture(env_region_file, env_file)
        env_region_file.unlink()
        assert not cfngin.should_skip()
        del cfngin.env_file  # clear cached value and force load
        assert not cfngin.should_skip(
            force=True)  # does not repopulate env_file
Example #12
0
    def test_find_config_files(self, tmp_path):
        """Test find_config_files."""
        bad_path = tmp_path / "bad_path"
        bad_path.mkdir()

        good_config_paths = [
            tmp_path / "_t3sT.yaml",
            tmp_path / "_t3sT.yml",
            tmp_path / "01-config.yaml",
            tmp_path / "01-config.yml",
            tmp_path / "TeSt_02.yaml",
            tmp_path / "TeSt_02.yml",
            tmp_path / "test.config.yaml",
            tmp_path / "test.config.yml",
        ]
        bad_config_paths = [
            tmp_path / ".anything.yaml",
            tmp_path / ".gitlab-ci.yml",
            tmp_path / "bitbucket-pipelines.yml",
            tmp_path / "buildspec.yml",
            tmp_path / "docker-compose.yml",
            bad_path / "00-invalid.yml",
        ]

        for config_path in good_config_paths + bad_config_paths:
            # python2 Path.write_text requires unicode
            config_path.write_text(u"")

        # support python < 3.6
        result = CFNgin.find_config_files(sys_path=str(tmp_path))
        expected = sorted([str(config_path) for config_path in good_config_paths])
        assert result == expected

        config_01 = tmp_path / "01-config.yml"
        result = CFNgin.find_config_files(
            sys_path=str(config_01)  # support python < 3.6
        )
        assert result == [str(config_01)]  # support python < 3.6

        result = CFNgin.find_config_files()
        assert not result
Example #13
0
    def test_plan(self, mock_action, cfngin_fixtures, tmp_path, patch_safehaven):
        """Test plan."""
        mock_instance = self.configure_mock_action_instance(mock_action)
        copy_basic_fixtures(cfngin_fixtures, tmp_path)

        context = self.get_context()
        cfngin = CFNgin(ctx=context, sys_path=str(tmp_path))
        cfngin.plan()

        mock_action.assert_called_once()
        mock_instance.execute.assert_called_once_with()
        patch_safehaven.assert_has_calls(
            [
                call(environ=context.env_vars),
                call.__enter__(),
                call(argv=["stacker", "diff", str(tmp_path / "basic.yml")]),
                call.__enter__(),
                call.__exit__(None, None, None),
                call.__exit__(None, None, None),
            ]
        )
Example #14
0
    def test_destroy(self, mock_action, cfngin_fixtures, tmp_path,
                     patch_safehaven):
        """Test destroy."""
        mock_instance = self.configure_mock_action_instance(mock_action)
        copy_basic_fixtures(cfngin_fixtures, tmp_path)

        context = self.get_context()
        cfngin = CFNgin(ctx=context, sys_path=str(tmp_path))
        cfngin.destroy()

        mock_action.assert_called_once()
        mock_instance.execute.assert_called_once_with(concurrency=0,
                                                      force=True,
                                                      tail=False)
        patch_safehaven.assert_has_calls([
            call(environ=context.env_vars),
            call.__enter__(),
            call(argv=['stacker', 'destroy',
                       str(tmp_path / 'basic.yml')]),
            call.__enter__(),
            call.__exit__(None, None, None),
            call.__exit__(None, None, None),
        ])
Example #15
0
    def test_env_file(self, tmp_path):
        """Test that the correct env file is selected."""
        test_env = tmp_path / "test.env"
        # python2 Path.write_text requires unicode
        test_env.write_text(u"test_value: test")

        # support python < 3.6
        result = CFNgin(ctx=self.get_context(), sys_path=str(tmp_path))
        assert result.env_file.test_value == "test"

        test_us_east_1 = tmp_path / "test-us-east-1.env"
        # python2 Path.write_text requires unicode
        test_us_east_1.write_text(u"test_value: test-us-east-1")

        test_us_west_2 = tmp_path / "test-us-west-2.env"
        # python2 Path.write_text requires unicode
        test_us_west_2.write_text(u"test_value: test-us-west-2")

        lab_ca_central_1 = tmp_path / "lab-ca-central-1.env"
        # python2 Path.write_text requires unicode
        lab_ca_central_1.write_text(u"test_value: lab-ca-central-1")

        # support python < 3.6
        result = CFNgin(ctx=self.get_context(), sys_path=str(tmp_path))
        assert result.env_file.test_value == "test-us-east-1"

        result = CFNgin(
            ctx=self.get_context(region="us-west-2"), sys_path=str(tmp_path)
        )  # support python < 3.6
        assert result.env_file.test_value == "test-us-west-2"

        result = CFNgin(
            ctx=self.get_context(name="lab", region="ca-central-1"),
            sys_path=str(tmp_path),
        )  # support python < 3.6
        assert result.env_file.test_value == "lab-ca-central-1"