示例#1
0
    def test_main_version_error(self, m_k8s):
        """Program must abort if it cannot get the version from K8s."""
        # Mock all calls to the K8s API.
        m_k8s.cluster_config.return_value = (None, True)

        with mock.patch("sys.argv", ["square.py", "get", "deploy"]):
            assert main.main() == 1
示例#2
0
    def test_main_invalid_option(self, m_k8s):
        """Simulate a missing or unknown option.

        Either way, the program must abort with a non-zero exit code.

        """
        # Do not pass any option.
        with mock.patch("sys.argv", ["square.py"]):
            with pytest.raises(SystemExit) as err:
                main.main()
            assert err.value.code == 2

        # Pass an invalid option.
        with mock.patch("sys.argv", ["square.py", "invalid-option"]):
            with pytest.raises(SystemExit) as err:
                main.main()
            assert err.value.code == 2
示例#3
0
    def test_main_create_default_config_file(self, tmp_path):
        """Create a copy of the default config config in the specified folder."""
        folder = tmp_path / "folder"

        with mock.patch("sys.argv", ["square.py", "config", "--folder", str(folder)]):
            assert main.main() == 0

        fname = (folder / ".square.yaml")
        assert DEFAULT_CONFIG_FILE.read_text() == fname.read_text()
示例#4
0
    def test_main_invalid_option_in_main(self, m_cluster, m_cmd, k8sconfig,
                                         fname_param_config):
        """Simulate an option that `square` does not know about.

        This is a somewhat pathological test and exists primarily to close some
        harmless gaps in the unit test coverage.

        """
        _, param, _ = fname_param_config

        # Pretend the call to get K8s credentials succeeded.
        m_cluster.side_effect = lambda *args: (k8sconfig, False)

        # Simulate an invalid Square command.
        param.parser = "invalid"
        m_cmd.return_value = param
        assert main.main() == 1

        # Force a configuration error due to the absence of K8s credentials.
        param.kubeconfig += "does-not-exist"
        m_cmd.return_value = param
        assert main.main() == 1
示例#5
0
    def test_main_nonzero_exit_on_error(self, m_apply, m_plan, m_get, m_k8s, k8sconfig):
        """Simulate sane program invocation.

        This test verifies that the bootstrapping works and the correct
        `main_*` function will be called with the correct parameters. However,
        each of those `main_*` functions returns with an error which means
        `main.main` must return with a non-zero exit code.

        """
        # Mock all calls to the K8s API.
        m_k8s.load_auto_config.return_value = k8sconfig
        m_k8s.session.return_value = "client"
        m_k8s.version.return_value = (k8sconfig, False)

        # Pretend all main functions return errors.
        m_get.return_value = (None, True)
        m_plan.return_value = (None, True)
        m_apply.return_value = (None, True)

        # Simulate all input options.
        for option in ["get", "plan", "apply"]:
            with mock.patch("sys.argv", ["square.py", option, "ns"]):
                assert main.main() == 1
示例#6
0
 def test_main_version(self):
     """Simulate "version" command."""
     with mock.patch("sys.argv", ("square.py", "version")):
         assert main.main() == 0
示例#7
0
    def test_main_valid_options(self, m_cluster, m_apply, m_plan, m_get,
                                tmp_path, fname_param_config, k8sconfig):
        """Simulate sane program invocation.

        This test verifies that the bootstrapping works and the correct
        `main_*` function will be called with the correct parameters.

        """
        _, _, config = fname_param_config
        m_cluster.side_effect = lambda *args: (k8sconfig, False)

        options = ["get", "plan", "apply"]

        # Pretend all functions return successfully.
        m_get.return_value = False
        m_plan.return_value = (None, False)
        m_apply.return_value = False

        # Simulate all input options.
        for option in options:
            args = (
                "square.py", option, *config.selectors.kinds,
                "--folder", str(config.folder),
                "--kubeconfig", str(config.kubeconfig),
                "--labels", "app=demo",
                "--namespace", "default",
            )
            with mock.patch("sys.argv", args):
                assert main.main() == 0
            del args

        # These two deviate from the values in `tests/support/config.yaml`.
        config.selectors.labels = ["app=demo"]
        config.selectors.namespaces = ["default"]

        # Every main function must have been called exactly once.
        m_get.assert_called_once_with(config)
        m_apply.assert_called_once_with(config, "yes")
        m_plan.assert_called_once_with(config)

        # Repeat the tests but with the "--info" flag. This must not call any
        # functions.
        m_get.reset_mock()
        m_apply.reset_mock()
        m_plan.reset_mock()

        for option in options:
            args = (
                "square.py", option, *config.selectors.kinds,
                "--folder", str(config.folder),
                "--kubeconfig", str(config.kubeconfig),
                "--labels", "app=demo",
                "--namespace", "default",
                "--info",
            )
            with mock.patch("sys.argv", args):
                assert main.main() == 0
            del args

        # These two deviate from the values in `tests/support/config.yaml`.
        config.selectors.labels = ["app=demo"]
        config.selectors.namespaces = ["default"]

        # Every main function must have been called exactly once.
        assert not m_get.called
        assert not m_apply.called
        assert not m_plan.called