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
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
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()
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
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
def test_main_version(self): """Simulate "version" command.""" with mock.patch("sys.argv", ("square.py", "version")): assert main.main() == 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